|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Announcements
Chapters
Services
Feature Zones
|
IntroductionThis code is a server control to publish your database structure (tables, columns, views, triggers, and stored procedures) on the web. It is written in VB.NET but could easily be written in any other language. The control can be nested in any ASPX page, to provide a nicely formatted database design document that is always up-to-date and available online.
BackgroundSQL Server stores all database object definitions in its system tables; therefore, it is easy to query it like any other set of database tables. In my example, the relevant dictionary tables are:
Partial diagram of SQL Server dictionary:
Another web control doing the same thing (in C# and XSLT instead of VB.NET) was published by Jose A. Gonzalvo. Because I'm using a different algorithm, and also because I am documenting stored procedures and trigger SQL scripts, I will offer my code to the community. Using the codeThis web control must be nested in an ASPX page like any other web control. It has a property called The sample project which comes with it includes a style sheet (with classes The codeMy code is divided in three parts:
The dictionary can be queried in different ways. Using SQL Server 2000, I wrote the following SQL: '### Objects (Tables, Views, Stored Procedures, Triggers) ###
sql = "SELECT id, name, rtrim(xtype) as xtype " & _
"FROM sysobjects SO " & _
"WHERE SO.status>-1 AND SO.xtype in ('U','V','P','TR') " & _
"ORDER BY name;"
'### Columns or Parameters ###
sql &= "SELECT SC.id, SC.name, SC.isnullable, ST.name AS typename, " & _
"CASE WHEN SC.xtype = 231 THEN SC.length/2" & _
" ELSE SC.length END AS length " & _
"FROM systypes ST, syscolumns SC, sysobjects SO " & _
"WHERE SC.xtype=ST.xtype " & _
" AND SC.id=SO.id" & _
" AND SO.status>-1 AND SO.xtype in ('U','V','P') " & _
" AND ST.length<>256 " & _
"ORDER BY SO.name, SC.colid;"
'### SQL Scripts ###
sql &= "SELECT SC.id, SC.text AS sql " & _
"FROM syscomments SC, sysobjects SO " & _
"WHERE SO.id=SC.id" & _
" AND SO.status>-1 AND SO.xtype in ('TR','V','P'); "
To handle data more efficiently, I submit my three queries at once and retrieve the result into a single Building the hierarchy and transforming the ds.DataSetName = "dbreport"
ds.Tables(0).TableName = "entity"
ds.Tables(1).TableName = "column"
ds.Tables(2).TableName = "definition"
MaxLoop = ds.Tables.Count - 1
For i = 0 To MaxLoop
With ds.Tables(i)
For j = 0 To .Columns.Count - 1
.Columns(j).ColumnName = LCase(.Columns(j).ColumnName)
.Columns(j).ColumnMapping = MappingType.Attribute
Next
.Columns("id").ColumnMapping = MappingType.Hidden
End With
Next
With ds
Dim rel1 As DataRelation = .Relations.Add("entity-column", _
ds.Tables("entity").Columns("id"), _
ds.Tables("column").Columns("id"))
rel1.Nested = True
Dim rel2 As DataRelation = .Relations.Add("entity-definition", _
ds.Tables("entity").Columns("id"), _
ds.Tables("definition").Columns("id"))
rel2.Nested = True
End With
myDOM.LoadXml(ds.GetXml)
The resulting XML will be as follows: <dbreport>
<entity name="Alphabetical list of products" xtype="V">
<column name="ProductID" isnullable="0"
typename="int" length="4" />
<column name="ProductName" isnullable="0"
typename="nvarchar" length="40" />
<column name="SupplierID" isnullable="1"
typename="int" length="4" />
<column name="CategoryID" isnullable="1"
typename="int" length="4" />
...
<definition sql="create view "Alphabetical list of products"
AS SELECT Products.*,
Categories.CategoryName FROM Categories
INNER JOIN Products ON Categories.CategoryID =
Products.CategoryID
WHERE (((Products.Discontinued)=0))" />
</entity>
...
</dbreport>
From this XML document, it is now easy to generate HTML. I do it, using NotesTo get column lengths, instead of querying CASE WHEN SC.xtype = 231 THEN SC.length/2 ELSE SC.length END AS length
in order to be consistent with Enterprise manager which displays For more information, a detailed description of SQL Server system tables is available on the MSDN web site.
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||