網路上流傳許多 SQL Server 資料字典的查詢語句,但品質參差不齊。筆者整理實務經驗,精簡出三個核心 SQL 視圖,涵蓋表結構、索引、主外鍵與程式物件,僅在 SQL Server 2000 測試通過,供參考。
查詢所有使用者資料表的欄位定義、主鍵、身分識別、預設值、說明等資訊:
SELECT TOP 100 PERCENT
CASE WHEN a.colorder = 1 THEN d.name ELSE '' END AS 表名,
CASE WHEN a.colorder = 1 THEN ISNULL(f.value, '') ELSE '' END AS 表說明,
a.colorder AS 字段序號,
a.name AS 字段名,
CASE WHEN COLUMNPROPERTY(a.id, a.name, 'IsIdentity') = 1 THEN '√' ELSE '' END AS 標識,
CASE WHEN EXISTS (
SELECT 1 FROM dbo.sysindexes si
INNER JOIN dbo.sysindexkeys sik ON si.id = sik.id AND si.indid = sik.indid
INNER JOIN dbo.syscolumns sc ON sc.id = sik.id AND sc.colid = sik.colid
INNER JOIN dbo.sysobjects so ON so.name = si.name AND so.xtype = 'PK'
WHERE sc.id = a.id AND sc.colid = a.colid
) THEN '√' ELSE '' END AS 主鍵,
b.name AS 類型,
a.length AS 長度,
COLUMNPROPERTY(a.id, a.name, 'PRECISION') AS 精度,
ISNULL(COLUMNPROPERTY(a.id, a.name, 'Scale'), 0) AS 小數位數,
CASE WHEN a.isnullable = 1 THEN '√' ELSE '' END AS 允許空,
ISNULL(e.text, '') AS 預設值,
ISNULL(g.[value], '') AS 字段說明,
d.crdate AS 建立時間,
CASE WHEN a.colorder = 1 THEN d.refdate ELSE NULL END AS 修改時間
FROM dbo.syscolumns a
LEFT OUTER JOIN dbo.systypes b ON a.xtype = b.xusertype
INNER JOIN dbo.sysobjects d ON a.id = d.id AND d.xtype = 'U' AND d.status >= 0
LEFT OUTER JOIN dbo.syscomments e ON a.cdefault = e.id
LEFT OUTER JOIN dbo.sysproperties g ON a.id = g.id AND a.colid = g.smallid AND g.name = 'MS_Description'
LEFT OUTER JOIN dbo.sysproperties f ON d.id = f.id AND f.smallid = 0 AND f.name = 'MS_Description'
ORDER BY d.name, a.colorder
列出各資料表的索引名稱、欄位、排序、是否為主鍵、叢集、唯一、填充因子等:
SELECT TOP 100 PERCENT
CASE WHEN b.keyno = 1 THEN c.name ELSE '' END AS 表名,
CASE WHEN b.keyno = 1 THEN a.name ELSE '' END AS 索引名稱,
d.name AS 列名,
b.keyno AS 索引順序,
CASE INDEXKEY_PROPERTY(c.id, b.indid, b.keyno, 'isdescending')
WHEN 1 THEN '降序' WHEN 0 THEN '升序' END AS 排序,
CASE WHEN p.id IS NULL THEN '' ELSE '√' END AS 主鍵,
CASE INDEXPROPERTY(c.id, a.name, 'IsClustered') WHEN 1 THEN '√' ELSE '' END AS 叢集,
CASE INDEXPROPERTY(c.id, a.name, 'IsUnique') WHEN 1 THEN '√' ELSE '' END AS 唯一,
CASE WHEN e.id IS NULL THEN '' ELSE '√' END AS 唯一約束,
a.OrigFillFactor AS 填充因子,
c.crdate AS 建立時間,
c.refdate AS 修改時間
FROM dbo.sysindexes a
INNER JOIN dbo.sysindexkeys b ON a.id = b.id AND a.indid = b.indid
INNER JOIN dbo.syscolumns d ON b.id = d.id AND b.colid = d.colid
INNER JOIN dbo.sysobjects c ON a.id = c.id AND c.xtype = 'U'
LEFT OUTER JOIN dbo.sysobjects e ON e.name = a.name AND e.xtype = 'UQ'
LEFT OUTER JOIN dbo.sysobjects p ON p.name = a.name AND p.xtype = 'PK'
WHERE OBJECTPROPERTY(a.id, N'IsUserTable') = 1
AND OBJECTPROPERTY(a.id, N'IsMSShipped') = 0
AND INDEXPROPERTY(a.id, a.name, 'IsAutoStatistics') = 0
ORDER BY c.name, a.name, b.keyno
一次查出主鍵、外鍵、約束、視圖、函數、預存程序、觸發器等物件及其建立腳本:
SELECT DISTINCT TOP 100 PERCENT
o.xtype,
CASE o.xtype
WHEN 'X' THEN '擴展預存程序' WHEN 'TR' THEN '觸發器'
WHEN 'PK' THEN '主鍵' WHEN 'F' THEN '外鍵' WHEN 'C' THEN '約束'
WHEN 'V' THEN '視圖' WHEN 'FN' THEN '函數-標量'
WHEN 'IF' THEN '函數-內嵌' WHEN 'TF' THEN '函數-表值'
ELSE '預存程序' END AS 類型,
o.name AS 物件名,
o.crdate AS 建立時間,
o.refdate AS 修改時間,
c.text AS 宣告語句
FROM dbo.sysobjects o
LEFT OUTER JOIN dbo.syscomments c ON o.id = c.id
WHERE o.xtype IN ('X','TR','C','V','F','IF','TF','FN','P','PK')
AND OBJECTPROPERTY(o.id, N'IsMSShipped') = 0
ORDER BY CASE o.xtype
WHEN 'X' THEN '擴展預存程序' WHEN 'TR' THEN '觸發器'
WHEN 'PK' THEN '主鍵' WHEN 'F' THEN '外鍵' WHEN 'C' THEN '約束'
WHEN 'V' THEN '視圖' WHEN 'FN' THEN '函數-標量'
WHEN 'IF' THEN '函數-內嵌' WHEN 'TF' THEN '函數-表值'
ELSE '預存程序' END DESC
這三個視圖即可快速產出完整資料字典,便於文件化與團隊協作。