2009-11-09 9 views
5

Estoy escribiendo una prueba de unidad C# que valida las propiedades de cadena para una clase ORM en la base de datos de destino, siempre SQL 2008 y la clase a la que se asignan los datos.SQL 2008 - Restricciones de clave externa en la vista INFORMATION_SCHEMA

Comprobación de que una clave externa especificada no es válida en el PP es fácil:

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

Ahora tome las siguientes relaciones de clave externa:

alt text

Mi pregunta: ¿Cómo puedo consultar la relación entre el 'Principal/Unique Key Base Table' y 'Primary/Unique Key Columns' lado? No puedo ver estos a los que se hace referencia en las vistas de INFORMATION_SCHEMA.

Gracias J

Respuesta

9

Este es el SQL que yo buscaba!

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

fantástico! Gracias. –

3

respuesta de Jaimie no puede devolver correctamente todas las claves externas si el cuadro mencionado (la tabla que la clave externa está buscando en contra) tiene una clave única, ya que utiliza la columna de la UNIQUE_CONSTRAINT_NAME. Sugiero:

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; 

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

Cuestiones relacionadas