2009-11-09 24 views
5

Bir ORM sınıfı için dize özelliklerini hedef veritabanına, her zaman SQL 2008'e ve verinin eşlediği sınıfa doğrulayan bir C# birim sınaması yazıyorum. Belirtilen yabancı anahtar DB geçerli olduğunu kontrol etmeSQL 2008 - INFORMATION_SCHEMA görünümünde yabancı anahtar kısıtlamaları

kolaydır:

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()); 
    } 

Şimdi aşağıdaki yabancı anahtar ilişkiler atın:

alt text

Benim sorum: Ben sorgulamak nasıl 'Birincil/Benzersiz Anahtar Tablosu' ve 'Birincil/Eşsiz Anahtar Sütunlar' tarafındaki ilişki? INFORMATION_SCHEMA görünümlerinde başvurulanları göremiyorum.

Teşekkür J

cevap

9

Bu peşinde olduğum SQL olduğunu!

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

Harika! Teşekkürler. –

3

Jaimie cevabı o UNIQUE_CONSTRAINT_NAME sütunu kullanması nedeniyle sevk tablo (yabancı anahtar karşı aradığını tablo) benzersiz bir anahtar varsa doğru tüm yabancı anahtarları dönmek için başarısız olur. Önerim:

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; 

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