join the MSSQLTips community

Today's Site Sponsor


 

Find performance issues related to Analysis Services memory limits.
 


Create a SQL Server Data Dictionary in Seconds using Extended Properties
Written By: Ken Simmons -- 5/15/2008 -- 9 comments -- printer friendly -- become a member


Tired of deadlocks, locking/blocking, slow queries and poor performance?

SQL performance tuning analyzes your SQL environment, identifies your performance issues, and provides solutions to fix your performance problems permanently.

We know where your performance problems are hiding


        Win SQL Books  -----  SharePoint Tips  -----  Live Webcast - SQL Backup Mistakes  -----  Bookmark and Share        

Problem
I need a way to create a data dictionary that will stay up to date. I make many changes to the database and I spend more time trying to keep the documentation updated than doing database administration.

Solution
You can create a data dictionary natively with SQL Server 2005 for a database in a few seconds if you store the metadata as extended properties. The SQL Server 2005 AdventureWorks sample database has numerous extended properties included, so this database serves as a great example.  In this tip we will cover two core topics.  First is sample set of scripts to add extended properties for a table as well as a column.  The second portion of the tip is T-SQL code to generate the data dictionary in HTML format.

Sample Scripts - sys.sp_addextendedproperty

The following is a sample script to add extended properties to the database.

Add Extended Properties to a Table and Column

/**********
The following extended properties already exist in the AdventureWorks database. There is no need to run the script against the database in order for the remaining samples to work.
**********/

USE [AdventureWorks]
GO

--Script to add an Extended Property to the Table
EXEC sys.sp_addextendedproperty
@name=N'MS_Description',
@value=N'Street address information for customers, employees, and vendors.' ,
@level0type=N'SCHEMA',
@level0name=N'Person', --Schema Name
@level1type=N'TABLE',
@level1name=N'Address' --Table Name
GO

--Script to add an Extended Property to a column
EXEC sys.sp_addextendedproperty
@name=N'MS_Description',
@value=N'First street address line.' ,
@level0type=N'SCHEMA',
@level0name=N'Person', --Schema Name
@level1type=N'TABLE',
@level1name=N'Address',--Table Name
@level2type=N'COLUMN',
@level2name=N'AddressLine1'--Column Name
GO

The extended properties can also be viewed by right clicking on an object in SSMS and selecting properties as shown below:

Once your database has data in the extended properties, you are ready to run the query to extract the data.  In SQL Server Management Studio select Tools | Options and in the Results to Text section uncheck the “Include column headers in the result set” option. This will keep all of the dashes out of the result set that show up under each column name.

Data Dictionary in HTML Format

Run the following script to generate the data dictionary and save the results to a file with an '.htm' extension.

Sample T-SQL Script to Generate a Data Dictionary

Set nocount on

DECLARE @TableName nvarchar(35)

DECLARE Tbls CURSOR
FOR

Select distinct Table_name
FROM INFORMATION_SCHEMA.COLUMNS
--put any exclusions here
--where table_name not like '%old'
order by Table_name

OPEN Tbls

PRINT '<HTML><body>'

FETCH NEXT FROM Tbls
INTO @TableName

WHILE @@FETCH_STATUS = 0
BEGIN

PRINT '</br>'
PRINT '<table border="1">'
Print '<B>' + @TableName + '</B>'
PRINT '</br>'
--Get the Description of the table
--Characters 1-250
Select substring(cast(Value as varchar(1000)),1,250) FROM
sys.extended_properties A
WHERE A.major_id = OBJECT_ID(@TableName)
and name = 'MS_Description' and minor_id = 0

--Characters 251-500
Select substring(cast(Value as varchar(1000)),251, 250) FROM
sys.extended_properties A
WHERE A.major_id = OBJECT_ID(@TableName)
and name = 'MS_Description' and minor_id = 0

PRINT '<tr><b>'
--Set up the Column Headers for the Table
PRINT '<td><b>Column Name</b></td>'
PRINT '<td><b>Description</b></td>'
PRINT '<td><b>InPrimaryKey</b></td>'
PRINT '<td><b>IsForeignKey</b></td>'
PRINT '<td><b>DataType</b></td>'
PRINT '<td><b>Length</b></td>'
PRINT '<td><b>Numeric Precision</b></td>'
PRINT '<td><b>Numeric Scale</b></td>'
PRINT '<td><b>Nullable</b></td>'
PRINT '<td><b>Computed</b></td>'
PRINT '<td><b>Identity</b></td>'
PRINT '<td><b>Default Value</b></td>'

--Get the Table Data
SELECT '</b></tr>',
'<tr>',
'<td>' + CAST(clmns.name AS VARCHAR(35)) + '</td>',
'<td>' + substring(ISNULL(CAST(exprop.value AS VARCHAR(255)),''),1,250),
substring(ISNULL(CAST(exprop.value AS VARCHAR(500)),''),251,250) + '</td>',
'<td>' + CAST(ISNULL(idxcol.index_column_id, 0)AS VARCHAR(20)) + '</td>',
'<td>' + CAST(ISNULL(
(SELECT TOP 1 1
FROM sys.foreign_key_columns AS fkclmn
WHERE fkclmn.parent_column_id = clmns.column_id
AND fkclmn.parent_object_id = clmns.object_id
), 0) AS VARCHAR(20)) + '</td>',
'<td>' + CAST(udt.name AS CHAR(15)) + '</td>' ,
'<td>' + CAST(CAST(CASE WHEN typ.name IN (N'nchar', N'nvarchar') AND clmns.max_length <> -1
THEN clmns.max_length/2
ELSE clmns.max_length END AS INT) AS VARCHAR(20)) + '</td>',
'<td>' + CAST(CAST(clmns.precision AS INT) AS VARCHAR(20)) + '</td>',
'<td>' + CAST(CAST(clmns.scale AS INT) AS VARCHAR(20)) + '</td>',
'<td>' + CAST(clmns.is_nullable AS VARCHAR(20)) + '</td>' ,
'<td>' + CAST(clmns.is_computed AS VARCHAR(20)) + '</td>' ,
'<td>' + CAST(clmns.is_identity AS VARCHAR(20)) + '</td>' ,
'<td>' + isnull(CAST(cnstr.definition AS VARCHAR(20)),'') + '</td>'
FROM sys.tables AS tbl
INNER JOIN sys.all_columns AS clmns
ON clmns.object_id=tbl.object_id
LEFT OUTER JOIN sys.indexes AS idx
ON idx.object_id = clmns.object_id
AND 1 =idx.is_primary_key
LEFT OUTER JOIN sys.index_columns AS idxcol
ON idxcol.index_id = idx.index_id
AND idxcol.column_id = clmns.column_id
AND idxcol.object_id = clmns.object_id
AND 0 = idxcol.is_included_column
LEFT OUTER JOIN sys.types AS udt
ON udt.user_type_id = clmns.user_type_id
LEFT OUTER JOIN sys.types AS typ
ON typ.user_type_id = clmns.system_type_id
AND typ.user_type_id = typ.system_type_id
LEFT JOIN sys.default_constraints AS cnstr
ON cnstr.object_id=clmns.default_object_id
LEFT OUTER JOIN sys.extended_properties exprop
ON exprop.major_id = clmns.object_id
AND exprop.minor_id = clmns.column_id
AND exprop.name = 'MS_Description'
WHERE (tbl.name = @TableName and
exprop.class = 1) --I don't wand to include comments on indexes
ORDER BY clmns.column_id ASC


PRINT '</tr></table>'

FETCH NEXT FROM Tbls
INTO @TableName
END


PRINT '</body></HTML>'

CLOSE Tbls
DEALLOCATE Tbls

Next Steps

  • The script can be scheduled to run as a job, so you will never have to worry about updating the documentation manually.
  • Since you are storing the documentation in the database, you never have to worry about having multiple copies and trying to figure out which one is current. It also gets backed up with the database.  So the value is very high.
  • The script will run without adding the extended properties, but obviously you will be missing the descriptions, so take some time and start adding the information to your environment.
Readers Who Read This Tip Also Read Comment or Ask Questions About This Tip Twitter This Tip!


Sponsor Information
Free SQL Server performance monitoring dashboard – Idera SQL check

Try SQL Object Level Recovery Native from Red Gate to save time and disk space. Download a free trial.

Need SQL Server Answers? Contact Edgewood for innovative and affordable consulting solutions

Prepare for your next SQL Server interview with CareerQandA.com

Top 10 SQL Server Backup Mistakes and How to Avoid Them web cast by Greg Robidoux - February 10, 2010

Make the most of MSSQLTips...Sign-up for the newsletter

Do you love this site and wish there was a SharePoint version?

Free Whitepaper - Streamline Backup & Recovery with LiteSpeed for SQL Server and LiteSpeed Engine for Oracle


 

 

DB Nitro - SQL Nitro

SQL Nitro sits between SQL Server & its clients, optimizing the normally inefficient TDS protocol. Optimize TDS & compress the data up to 80%, reduce SQL bandwidth by 50%, & improve response times over 65%!

Download now!



More SQL Server Tools
SQL comparison toolset

SQL Nitro

SQL Backup

SQL diagnostic manager

SQL defrag manager




Copyright (c) 2006-2010 Edgewood Solutions, LLC All rights reserved
privacy statement | disclaimer | copyright | advertise | write for mssqltips | feedback | about
Some names and products listed are the registered trademarks of their respective owners.