5

I am writing a c# unit test that validates string properties for an ORM class against the target database, always SQL 2008, and the class that the data maps to.

Checking that a specified foreign key is valid in the DB is easy:

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

Now take the following Foreign Key Relationships:

alt text

My question: How do I query the relationship from the 'Primary/Unique Key Base Table' and 'Primary/Unique Key Columns' side? I cannot see these referenced in the INFORMATION_SCHEMA views.

Thanks J

2 Answers 2

9

This is the SQL that I was after!

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 
Sign up to request clarification or add additional context in comments.

Comments

3

Jaimie's answer fails to correctly return all the foreign keys if the referred table (the table that the foreign key is looking against) has a unique key because it uses the UNIQUE_CONSTRAINT_NAME column. I suggest:

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;

Source:

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.