2009-11-12 91 views
1

我曾經使用'GetSchemaTable'來讀取模式信息,但它缺少一些'東西',所以我編寫了一個大查詢,引用了其他列中的sys.columns ,sys.index_columns和sys.indexes(以及其他表)返回我用於從GetSchemaTable獲取的相同信息,並返回我想要的其他信息。如何識別視圖中的PK列

問題是,GetSchemaTable會告訴我從視圖返回的列是基礎表的Key列,但是我的新查詢沒有。它會整天爲我提供正確的答案,而不是意見。

有沒有人有一個解決的辦法?當我檢查一個視圖時,我不想回到GetSchemaTable僅僅爲了那一點信息。 (另外,我真的只想要一個基於SQL的解決方案,理想情況。)

謝謝!

回答

1

不幸的是,在SQL Server 2005中,這不是很容易。我已經玩了一下,它非常接近,但它依賴於您在視圖中命名列與您在基表中命名完全相同的事實。這是因爲現在不推薦使用SQL Server 2008的視圖sys.sql_dependencies不能正確存儲引用column_id,因此無法將其與視圖中的實際列進行匹配。我認爲SQL Server 2008將爲你提供更好的選擇,因爲它們又引入了一組新的依賴對象。我也沒有使用INFORMATION_SCHEMA.KEY_COLUMN_USAGE追蹤任何路徑,但由於這些視圖完全依賴於名稱而不是任何類型的id,所以您可能會在同一個pickle中進行搜索。所以也許這可以成爲你的開始,但正如我所說,這隻會涵蓋簡單的情況。如果你別名你的專欄,你將會運氣不佳。也許別人有一些瞭解這些東西是如何引用將一隻兔子出來,並找出如何引用列不匹配的複雜性......

-- very simple; one-column key: 

CREATE TABLE dbo.boo 
(
    far INT PRIMARY KEY 
); 
GO 

CREATE VIEW dbo.view_boo 
AS 
    SELECT far FROM dbo.boo; 
GO 

-- slightly more complex. Two-column key, 
-- not all columns are in key, view columns 
-- are in different order: 

CREATE TABLE dbo.foo 
(
    splunge INT, 
    a INT, 
    mort INT, 
    PRIMARY KEY(splunge, mort) 
); 
GO 

CREATE VIEW dbo.view_foo 
AS 
    SELECT 
     splunge, 
     mort, 
     a 
    FROM 
     dbo.foo; 
GO 

SELECT 
    QUOTENAME(OBJECT_SCHEMA_NAME(v.[object_id])) + '.' 
    + QUOTENAME(v.name) + '.' + QUOTENAME(vc.name) 
    + ' references ' 
    + QUOTENAME(OBJECT_SCHEMA_NAME(t.[object_id])) 
    + '.' + QUOTENAME(t.name) + '.' + QUOTENAME(tc.name) 
FROM 
    sys.views AS v 
INNER JOIN 
    sys.sql_dependencies AS d 
    ON v.[object_id] = d.[object_id] 
INNER JOIN 
    sys.tables AS t 
    ON d.referenced_major_id = t.[object_id] 
INNER JOIN 
    sys.columns AS tc 
    ON tc.[object_id] = t.[object_id] 
INNER JOIN 
    sys.index_columns AS ic 
    ON tc.[object_id] = ic.[object_id] 
    AND tc.column_id = ic.column_id 
    AND tc.column_id = d.referenced_minor_id 
INNER JOIN 
    sys.columns AS vc 
    ON vc.[object_id] = v.[object_id] 
    AND vc.name = tc.name -- the part I don't like 
INNER JOIN 
    sys.indexes AS i 
    ON ic.[object_id] = i.[object_id] 
    AND i.is_primary_key = 1 
ORDER BY 
    t.name, 
    ic.key_ordinal; 

GO 

DROP VIEW dbo.view_boo, dbo.view_foo; 
DROP TABLE dbo.foo, dbo.boo; 
+0

我會玩這個多一些時間允許,我我確信有一種方法可以做到這一點(畢竟優化器必須能夠做到這一點),但這就是我現在所擁有的一切......希望它能爲您提供一個開始。 – 2009-11-12 23:43:40