![]() |
|
|
By: Armando Prato | Read Comments (2) | Print Armando has over 24 years of industry experience and has been working with SQL Server since version 6.5. Related Tips: More |
|
Problem
My company sells a packaged software solution to our customers. From time to time, I am called in to troubleshoot and diagnose customer database issues. A lot of times, I find that our support department has added indexes to the customer's model or modified their database source code. Unfortunately, I have to comb through the database to find these changes. Is there a better way?
Solution
Alas, in the past I used to run into this quite frequently. Changes would get made, they would never get communicated, and I'd find myself going down rabbit holes only to discover that a change was made after delivery of the software.
For every software release, I now maintain metadata tables about what makes up my database. I am diligent about naming every single object in my schema whether it be a CHECK constraint, a DEFAULT constraint, etc. If it goes into the database, it gets a name... allowing a SQL Server system generated name in my model is unacceptable!
In my model, I create and maintain 2 metadata tables. The first table contains a list of all the objects that make up a standard, delivered database (i.e. tables, constraints, stored procedures, etc). The 2nd table is a child table that lists all the columns, their datatypes, their ordinal position, etc for each object defined in the primary table (if applicable). I can then execute a stored procedure that I've written that compares the metadata tables of the current database against the INFORMATION_SCHEMA views along with select system tables to get an idea of what differences (if any) have been made to the database after it has been installed.
The following scaled down sample script ilustrates this concept. It first creates a parent table that catalogs all objects that make my database. It then creates a child table that catalogs all columns that make up each of the parent entries provided that parent entry is a table, index, foreign key, etc. The 2 tables are populated with metadata based on a schema table called Customer. I catalog the table, the table's columns and ordinal positions, the primary key, the PK's column, and the stored procedure I created along with it's length in bytes. Capturing the stored procedure's length in bytes, I can get an idea if a procedure has changed . It gives me a head's up that I may have to look at this procedure a little bit more closely.
-- create table to hold schema objects |
I will now create a database schema checking program that can be used to read these tables and determine if the database has changed from its originally released version. In this sample, I will check to make sure all tables are present and that no stored procedures have changed.
CREATE PROCEDURE dbo.CheckDatabase |
You should see the following output
Now, let's assume that a developer modified the GetCustomer stored procedure to accept a passed in customerid. Re-running our database check procedure, we can capture that something has changed in the database.
ALTER PROCEDURE dbo.GetCustomer @customerid INT |
As you can see, you can get a good idea of any database changes that have occurred before you dig into a problem which can save you a lot of wasted investigative time.
Next Steps
| Share: | Share | Tweet |
|
![]() |
![]() |
Free SQL Server Learning |
| Tuesday, September 09, 2008 - 8:41:40 AM - lpesdan | Read The Tip |
|
To store all the database objects again in a SQL database with there definition is redundant and old school. Use the service broker and have it write any changes in the schema of sql to a database. This is realtime and you don't need to poll all the object every day to see what changed. You will need to create a table for the audited changes and a stored procedure to grab the changes from the broker. This will save you allot of resources and time.
---------------------------------------------------------------------------------------- DROP EVENT NOTIFICATION Audit_Notify_DB_Changes ON SERVER --Create a queue to receive messages.
TO SERVICE 'NotifyService', 'current database' ALTER QUEUE [dbo].[NotifyQueue]
|
|
| Tuesday, September 09, 2008 - 10:36:53 AM - aprato | Read The Tip |
|
Hi Thanks for the alternate solution. In my situation, it's not feasible to expect that all our customers (hundreds of them) will have SB enabled. In some cases, our customers dictate to us what they allow to be enabled and what they don't (for instance, xp_cmdshell). The software is shipped to the customer where it is installed on their server. It may be modified manually either by them or by a support rep after the fact. The tables represent the structure of the database as it was shipped to the customer. Once they get the software and install it, it's out of our hands as their DBA's (if they have one - a lot of times it's an application developer who has some basic knowledge of SQL Server) take over. Using the approach in the tip, I know I can always interrogate what's in the tables vs what's in the catalogs and know what has definitely changed. I don't have to worry if the customer has disabled Service Broker (on purpose or accidentally). |
|
|
privacy | disclaimer | copyright | advertise | about authors | contribute | feedback | giveaways | user groups Some names and products listed are the registered trademarks of their respective owners. Edgewood Solutions LLC | MSSharePointTips.com | MSSQLTips.com |