2009-11-09 52 views
5

我正在编写一个c#单元测试,用于针对目标数据库,总是SQL 2008以及数据映射到的类验证ORM类的字符串属性。SQL 2008 - INFORMATION_SCHEMA视图中的外键约束

检查指定的外键是在DB有效很简单:

static private bool ConstraintExsits(string table, string column, ConstraintType constraintType) 
    { 
     string constraintTypeWhereClause; 
     switch (constraintType) 
     { 
      case ConstraintType.PrimaryKey: 
       constraintTypeWhereClause = "PRIMARY KEY"; 
       break; 
      case ConstraintType.ForeignKey: 
       constraintTypeWhereClause = "FOREIGN KEY"; 
       break; 
      default: 
       throw new ArgumentOutOfRangeException("constraintType"); 
     } 

     var cmd = new SqlCommand(
          @"SELECT a.CONSTRAINT_NAME 
          FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS a 
          JOIN INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE b on a.CONSTRAINT_NAME = b.CONSTRAINT_NAME 
          WHERE a.TABLE_NAME = @table AND b.COLUMN_NAME = @column AND a.CONSTRAINT_TYPE = '" + constraintTypeWhereClause + "'", 
          Connection); 
     cmd.Parameters.AddWithValue("@table", table.Trim('[').Trim(']')); 
     cmd.Parameters.AddWithValue("@column", column.Trim('[').Trim(']')); 
     return !string.IsNullOrEmpty((string)cmd.ExecuteScalar()); 
    } 

现在采取以下外键关系:

alt text

我的问题:我如何查询'Primary/Unique Key Base Table'和'Primary/Unique Key Columns'边的关系?我无法在INFORMATION_SCHEMA视图中看到这些引用。

感谢 Ĵ

回答

9

这是我后的SQL!

SELECT 
FK_Table = FK.TABLE_NAME, 
FK_Column = CU.COLUMN_NAME, 
PK_Table = PK.TABLE_NAME, 
PK_Column = PT.COLUMN_NAME, 
Constraint_Name = C.CONSTRAINT_NAME 
FROM 
INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS C 
INNER JOIN 
INFORMATION_SCHEMA.TABLE_CONSTRAINTS FK 
    ON C.CONSTRAINT_NAME = FK.CONSTRAINT_NAME 
INNER JOIN 
INFORMATION_SCHEMA.TABLE_CONSTRAINTS PK 
    ON C.UNIQUE_CONSTRAINT_NAME = PK.CONSTRAINT_NAME 
INNER JOIN 
INFORMATION_SCHEMA.KEY_COLUMN_USAGE CU 
    ON C.CONSTRAINT_NAME = CU.CONSTRAINT_NAME 
INNER JOIN 
( 
    SELECT 
     i1.TABLE_NAME, i2.COLUMN_NAME 
    FROM 
     INFORMATION_SCHEMA.TABLE_CONSTRAINTS i1 
     INNER JOIN 
     INFORMATION_SCHEMA.KEY_COLUMN_USAGE i2 
     ON i1.CONSTRAINT_NAME = i2.CONSTRAINT_NAME 
     WHERE i1.CONSTRAINT_TYPE = 'PRIMARY KEY' 
) PT 
ON PT.TABLE_NAME = PK.TABLE_NAME 
+0

太棒了!谢谢。 – 2012-10-25 21:12:30

3

贾米的回答未能正确地返回所有的外键,如果提及表(外键正在对表)具有独特的关键,因为它使用的UNIQUE_CONSTRAINT_NAME列。我建议:

SELECT 
    FK = fk.name, 
    FKTable = QUOTENAME(OBJECT_SCHEMA_NAME(fkcol.[object_id])) 
     + '.' + QUOTENAME(OBJECT_NAME(fkcol.[object_id])), 
    FKCol = fkcol.name, 
    ' references => ', 
    PKTable = QUOTENAME(OBJECT_SCHEMA_NAME(pkcol.[object_id])) 
     + '.' + QUOTENAME(OBJECT_NAME(pkcol.[object_id])), 
    PKCol = pkcol.name 
FROM sys.foreign_keys AS fk 
INNER JOIN sys.foreign_key_columns AS fkc 
ON fk.[object_id] = fkc.constraint_object_id 
INNER JOIN sys.columns AS fkcol 
ON fkc.parent_object_id = fkcol.[object_id] 
AND fkc.parent_column_id = fkcol.column_id 
INNER JOIN sys.columns AS pkcol 
ON fkc.referenced_object_id = pkcol.[object_id] 
AND fkc.referenced_column_id = pkcol.column_id 
ORDER BY fkc.constraint_column_id; 

来源:http://sqlblog.com/blogs/aaron_bertrand/archive/2011/11/03/the-case-against-information-schema-views.aspx