用于在 HTML 中生成数据库设计文档的 Web 控件






4.59/5 (10投票s)
仅用200行VB.NET代码来记录你的SQL Server数据库。
引言
这段代码是一个服务器控件,用于在Web上发布你的数据库结构(表、列、视图、触发器和存储过程)。它是用VB.NET编写的,但可以很容易地用任何其他语言编写。 该控件可以嵌套在任何ASPX页面中,以提供一个格式良好的数据库设计文档,该文档始终是最新的并可在线访问。
背景
SQL Server将其所有数据库对象定义存储在其系统表中;因此,像查询任何其他数据库表一样查询它是很容易的。在我的示例中,相关的字典表是
- sysobjects(包含表、视图、存储过程和触发器的名称)。
- syscolumns(包含列和存储过程参数名称)。
- systypes(包含在企业管理器中显示的列类型)。
- syscomments(包含视图、存储过程和触发器的SQL脚本)。
SQL Server字典的部分图表
另一个执行相同操作的Web控件(用C#和XSLT代替VB.NET)由Jose A. Gonzalvo发布。因为我使用不同的算法,并且我还记录了存储过程和触发器SQL脚本,所以我将我的代码提供给社区。
使用代码
这个Web控件必须像任何其他Web控件一样嵌套在ASPX页面中。它有一个名为SqlConnection
的属性,用于指定数据库连接字符串。 必须授予用户对系统表的读取权限。
随附的示例项目包含一个样式表(具有类RowHeader
、RowOdd
、RowEven
和SQL
)以及一些图片,使其看起来很漂亮。 不要忘记将它们包含在你的项目中。
代码
我的代码分为三个部分
- 查询字典
- 将数据集组织成层次结构
- 渲染HTML
可以用不同的方式查询字典。 使用SQL Server 2000,我编写了以下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'); "
为了更有效地处理数据,我一次提交我的三个查询,并将结果检索到单个DataSet
中。
将层次结构构建并将DataSet
转换为XML的方法如下
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)
生成的XML将如下所示
<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>
从这个XML文档中,现在很容易生成HTML。我使用System.Text.StringBuilder
来执行此操作,使用我的XML文档的元素和属性来连接HTML标记的字符串。 这种最后的转换也可以使用XSLT来完成。
注释
为了获取列长度,我使用以下SQL代替查询syscolumns.length
CASE WHEN SC.xtype = 231 THEN SC.length/2 ELSE SC.length END AS length
为了与Enterprise manager保持一致,后者显示 nvarchar
作为字符串长度,而不是存储它所需的空间。
有关更多信息,请访问MSDN网站,其中提供了SQL Server系统表的详细说明。