2009-11-12 49 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