join the MSSQLTips community

Today's Site Sponsor


 

SQL Compare quickly and easily compares and synchronizes SQL Server database schemas
 



I generated better data in only seconds...

Script to build a SQL Server Data Dictionary and report with Microsoft Excel

Written By: Kun Lee -- 12/2/2008 -- read/post comments -- print -- Bookmark and Share

Rating: (not rated yet) Rate

Problem
In an earlier tip (Building a SQL Server Data Dictionary with the Extended Properties and Third Party Tools) I outlined the value of using the extended properties across some of the industry leading data modeling tools.  What if I do not have access to any of those tools?  Is it possible to build the extended properties and then be able to generate reports by using Excel or Reporting Services?  How can I capture the data dictionary at a point in time?

Solution
That is a great question.  The easiest way to solve this problem is capture the values from the extended properties into physical table so that you can easily export the data by using Microsoft Excel, Reporting Services or any other reporting tool.


To start the process you need do deploy the store procedure dbo.sp_get_extendedproperty outlined below. 

[dbo].[sp_get_extendedproperty]

USE [master]
GO
CREATE PROCEDURE [dbo].[sp_get_extendedproperty]
@databasename varchar(128) = NULL
as

BEGIN
SET NOCOUNT ON
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED


IF @databasename IS NULL
SET @databasename = db_name()

DECLARE @sqltext nvarchar(4000)

IF object_id(N'tempdb.dbo.##temp___DataDictionary') IS NOT NULL
DROP TABLE ##temp___DataDictionary

IF object_id(N'tempdb.dbo.##temp___DataDictionary_schema') IS NOT NULL
DROP TABLE ##temp___DataDictionary_schema


CREATE TABLE ##temp___DataDictionary(
[tableschema] varchar(128) NULL,
[tablename] varchar(128) NULL,
[columnname] varchar(128) NULL,
[xtype] varchar(8) NULL,
[description] nvarchar(4000) NULL
)

CREATE TABLE ##temp___DataDictionary_schema(
[tableschema] varchar(128),
[tablename] varchar(128) NULL,
)

-- Deploy Database Property
SET @sqltext = 'INSERT INTO ##temp___DataDictionary ([description], [xtype]) SELECT cast(value as nvarchar(4000)), ''D'' FROM '
+ @databasename + '.sys.fn_listextendedproperty(default, default, default, default, default, default, default)'

EXECUTE (@sqltext)

-- Get table level data dictionary

SET @sqltext = 'INSERT INTO ##temp___DataDictionary_schema SELECT DISTINCT TABLE_SCHEMA, TABLE_NAME FROM '
+ @databasename + '.INFORMATION_SCHEMA.TABLES'
EXECUTE(@sqltext)

DECLARE table_cursor CURSOR FOR
SELECT DISTINCT [tableschema] FROM ##temp___DataDictionary_schema

DECLARE @TABLE_SCHEMA VARCHAR(128)

OPEN table_cursor
FETCH NEXT FROM table_cursor INTO @TABLE_SCHEMA

WHILE @@FETCH_STATUS = 0
BEGIN

SET @sqltext = 'INSERT INTO ##temp___DataDictionary ([tableschema], [tablename],[description], [xtype]) SELECT '
+ '''' + @TABLE_SCHEMA + '''' + + ', objname, cast(value as nvarchar(4000)), ''U'' FROM '
+ @databasename + '.sys.fn_listextendedproperty (NULL, ''schema'', '
+ '''' + @TABLE_SCHEMA + ''''+ ', ''table'', default, NULL, NULL)'

EXECUTE(@sqltext)

FETCH NEXT FROM table_cursor INTO @TABLE_SCHEMA
END

CLOSE table_cursor
DEALLOCATE table_cursor

CREATE TABLE ##temp___DataDictionary_keys(
[tableschema] varchar(128) NULL,
[tablename] varchar(128) NULL,
[columnname] varchar(128) NULL,
[xtype] varchar(8) NULL
)

-- Populate all the key types
SET @sqltext = 'INSERT INTO ##temp___DataDictionary_keys SELECT U.TABLE_SCHEMA,U.TABLE_NAME, U.COLUMN_NAME, xtype '
+ 'FROM ' + @databasename + '.INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE U '
+ 'JOIN ' + @databasename + '.sys.sysobjects O ON U.CONSTRAINT_NAME = O.name WHERE O.xtype in (''F'',''PK'')'
EXECUTE(@sqltext)

-- Get column level
DECLARE @TABLE_NAME varchar(128)

DECLARE column_cursor CURSOR FAST_FORWARD FOR
SELECT [tableschema], [tablename] FROM ##temp___DataDictionary_schema

OPEN column_cursor
FETCH NEXT FROM column_cursor INTO @TABLE_SCHEMA, @TABLE_NAME

WHILE @@FETCH_STATUS = 0
BEGIN
-- display all columns under MyTable
SET @sqltext = 'INSERT INTO ##temp___DataDictionary ([tableschema], [tablename],[columnname], [description]) SELECT '
+ '''' + @TABLE_SCHEMA + '''' + ','
+ '''' + @TABLE_NAME + '''' + ', objname, cast(value as nvarchar(4000))'
+ ' FROM ' + @databasename + '.sys.fn_listextendedproperty (NULL, ''schema'', '
+ '''' + @TABLE_SCHEMA + '''' + ', ''table'', '
+ '''' + @TABLE_NAME + '''' + ', ''column'', default)'

EXECUTE(@sqltext)

FETCH NEXT FROM column_cursor INTO @TABLE_SCHEMA, @TABLE_NAME
END

CLOSE column_cursor
DEALLOCATE column_cursor

UPDATE D
SET D.[xtype] = K.[xtype]
FROM ##temp___DataDictionary D JOIN ##temp___DataDictionary_keys K
ON D.tableschema = K.tableschema AND D.tablename = K.tablename AND D.columnname = K.columnname

SELECT @@servername as servername,@databasename as dbname,tableschema,tablename,columnname,[xtype],[description]
FROM ##temp___DataDictionary
ORDER BY @@servername ,dbname,tableschema,tablename,columnname,[xtype] asc

DROP TABLE ##temp___DataDictionary

DROP TABLE ##temp___DataDictionary_keys

END

Second, you need to create a database and table to store the data for reporting purposes.  For this tip, I have created a database called 'DBA' and a table called 'DataDictionary' to store the final data for reporting purposes.

-- Create DBA Database
CREATE DATABASE DBA
GO

USE DBA
-- Create Table
CREATE TABLE [dbo].[DataDictionary](
[sqlinstance] [varchar](128) NOT NULL,
[databasename] [varchar](128) NOT NULL,
[tableschema] [varchar](128) NULL,
[tablename] [varchar](128) NULL,
[columnname] [varchar](128) NULL,
[xtype] [varchar](8) NULL,
[description] [nvarchar](4000) NULL
)

Third, let's run the stored procedure to populate the table with the data from the "AdventureWorks2008" database for this sample.

INSERT INTO DBA.dbo.[DataDictionary] exec sp_get_extendedproperty 'AdventureWorks2008'

Now, you can use one of the well known Microsoft SQL Server system store procedures 'sp_MSforeachdb' to populate the table from each of the databases.

TRUNCATE TABLE DBA.dbo.[DataDictionary]
EXEC master.sys.sp_MSforeachdb 'INSERT INTO DBA.dbo.[DataDictionary] exec sp_get_extendedproperty "?"'

Now, if you issue a simple select statement against the [dbo].[DataDictionary] table, you will see results like this:


Now, you just need to report on the data from the [dbo].[DataDictionary] table.  Check out the tips below to report on the data from Excel, Reporting Service, Access, etc.

Here is a sample result set in Excel:


So, now you have it.  Wasn't that easy to manage?  Here is another reason to use Extended Properties to build a Data Dictionary.

Next Steps

  • Keep in mind how easy it is to build and use the Extended Properties to build a Data Dictionary and leverage third party tools or your own solution.
  • If you build your own solution, you can setup Reporting Services or Excel to extract the data dictionary and share it with users.
  • If you have a lot of servers, I would consider writing an SSIS package to pull the data from all the server into one repository.  In the table used in this tip, that is the reason I included the SQL instance name.
  • If you want to force SQL Server Developer to force to fill out data dictionary, you can also modify the query and write an alert based on missing data dictionary values and send the report to the application owner to update the data dictionary.
Readers Who Read This Tip Also Read Free Live Webcast Comment or Ask Questions About This Tip


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

Realistic test data in just one click with SQL Data Generator.

SQL Server Consultants - What you don't know could be your biggest asset - Guaranteed Results

Attend a SQL Server Conference for Free

Free SQL Server web casts for DBAs and Developers on Performance Tuning, Development, Administration, Disaster Recovery, Replication and more....


Get Our Tips Newsletter

We keep 50,000+ SQL Server professionals informed.

Idera - SQL diagnostic manager

Idera SQL diagnostic manager is an award-winning performance monitoring solution for SQL Server that provides agent-less, real-time monitoring, customizable alerting, and extensive historical reporting. SQL diagnostic manager also puts must-have troubleshooting information at the DBA’s fingertips such as worst-performing code, long-running or frequently run queries, and blocking or blocked sessions.

Download now!



More SQL Server Tools
SQL Refactor

SQL compliance manager

SQL Data Generator

SQL diagnostic manager

SQL safe backup




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.


CareerQandA.com | MSSharePointTips.com | MSSQLTips.com