資料庫按規定進行故障排除的時候,需要對資料庫中50個表的每一個都進行查看,以確保所有期望是預設值的欄位都被分配了預設值。可以想象這是一個多麼令人畏懼的工作,有沒有一個比在SQL Server管理套件中開啟每一個表來查看這個schema的更好方法嗎?
通過查詢任何資料庫中的三個系統資料表,你可以獲得每個表的每一個欄位的預設值。下面是這個核心查詢。它返回分配給當前資料庫中每個使用者表的預設值。這個查詢在SQL 2000和SQL 2005中都是相容的。
SELECT SO.NAME AS "Table Name", SC.NAME AS "Column Name", SM.TEXT AS "Default Value"
FROM dbo.sysobjects SO INNER JOIN dbo.syscolumns SC ON SO.id = SC.id
LEFT JOIN dbo.syscomments SM ON SC.cdefault = SM.id
WHERE SO.xtype = 'U'
ORDER BY SO.[name], SC.colid
sysobjects 為我們提供了表中繼資料。考試大整理的例子中,只對錶名稱感興趣。syscolumns 表格儲存體與每個表的各個欄位相關聯的中繼資料。在這個例子中,我們只需要欄位名稱。最後,預設值中繼資料由syscomments表提供。
對Northwind資料庫運行這個查詢產生下面的結果(為了簡短,省略了一些記錄)。注意,因為LEFT JOIN到syscomments表所以它將返回NULL預設值。
選擇1:搜尋特別的預設值
通過編輯WHERE條件陳述式,我們可以在所有的表中查看特別的預設值。
SELECT SO.NAME AS "Table Name", SC.NAME AS "Column Name", SM.TEXT AS "Default Value"
FROM dbo.sysobjects SO INNER JOIN dbo.syscolumns SC ON SO.id = SC.id
LEFT JOIN dbo.syscomments SM ON SC.cdefault = SM.id
WHERE SO.xtype = 'U' AND SM.TEXT = '(0)'
ORDER BY SO.[name], SC.colid
選擇2:只返回具有預設值欄位的資訊
修改核心查詢的WHERE條件陳述式來忽略syscomments.text表中的NULL值,這個技巧如下所示:
SELECT SO.NAME AS "Table Name", SC.NAME AS "Column Name", SM.TEXT AS "Default Value"
FROM dbo.sysobjects SO INNER JOIN dbo.syscolumns SC ON SO.id = SC.id
LEFT JOIN dbo.syscomments SM ON SC.cdefault = SM.id
WHERE SO.xtype = 'U' AND SM.TEXT IS NOT NULL
ORDER BY SO.[name], SC.colid
但是,將FROM條件從句中的JOIN從一個LEFT JOIN改為一個INNER JOIN會提供最佳化:
SELECT SO.NAME AS "Table Name", SC.NAME AS "Column Name", SM.TEXT AS "Default Value"
FROM dbo.sysobjects SO INNER JOIN dbo.syscolumns SC ON SO.id = SC.id
INNER JOIN dbo.syscomments SM ON SC.cdefault = SM.id
WHERE SO.xtype = 'U'
ORDER BY SO.[name], SC.colid
其實還有另一個選擇,利用SQL 2005中的系統目錄檢視。前面的查詢給我提供了這時所需要的資訊,並在SQL 2000和SQL 2005中都可以使用,在SQL2000執行個體中可以挖掘出與這個預設值(實際上是一個預設約束)關聯的額外中繼資料。通過將這個查詢特定在系統目錄檢視上,我們可以獲得在之前的查詢中沒有顯示出來的額外資訊。
SELECT ST.[name] AS "Table Name", SC.[name] AS "Column Name", SD.definition AS "Default Value", SD.[name] AS "Constraint Name"
FROM sys.tables ST INNER JOIN sys.syscolumns SC ON ST.[object_id] = SC.[id]
INNER JOIN sys.default_constraints SD ON ST.[object_id] = SD.[parent_object_id] AND SC.colid = SD.parent_column_id
ORDER BY ST.[name], SC.colid
被告知沒有更好的方法,依靠你作為一個資料庫管理員的本能來鑽研。你永遠不會知道你可能會得到些什麼