2009-11-09 46 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