SQL Server: Howto Get Foreign Key Reference from Information_Schema

SQL Server: Howto get foreign key reference from information_schema?

Never mind, this is the correct answer:

http://msdn.microsoft.com/en-us/library/aa175805(SQL.80).aspx

SELECT 
KCU1.CONSTRAINT_SCHEMA AS FK_CONSTRAINT_SCHEMA
,KCU1.CONSTRAINT_NAME AS FK_CONSTRAINT_NAME
,KCU1.TABLE_SCHEMA AS FK_TABLE_SCHEMA
,KCU1.TABLE_NAME AS FK_TABLE_NAME
,KCU1.COLUMN_NAME AS FK_COLUMN_NAME
,KCU1.ORDINAL_POSITION AS FK_ORDINAL_POSITION
,KCU2.CONSTRAINT_SCHEMA AS REFERENCED_CONSTRAINT_SCHEMA
,KCU2.CONSTRAINT_NAME AS REFERENCED_CONSTRAINT_NAME
,KCU2.TABLE_SCHEMA AS REFERENCED_TABLE_SCHEMA
,KCU2.TABLE_NAME AS REFERENCED_TABLE_NAME
,KCU2.COLUMN_NAME AS REFERENCED_COLUMN_NAME
,KCU2.ORDINAL_POSITION AS REFERENCED_ORDINAL_POSITION
FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS AS RC

INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS KCU1
ON KCU1.CONSTRAINT_CATALOG = RC.CONSTRAINT_CATALOG
AND KCU1.CONSTRAINT_SCHEMA = RC.CONSTRAINT_SCHEMA
AND KCU1.CONSTRAINT_NAME = RC.CONSTRAINT_NAME

INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS KCU2
ON KCU2.CONSTRAINT_CATALOG = RC.UNIQUE_CONSTRAINT_CATALOG
AND KCU2.CONSTRAINT_SCHEMA = RC.UNIQUE_CONSTRAINT_SCHEMA
AND KCU2.CONSTRAINT_NAME = RC.UNIQUE_CONSTRAINT_NAME
AND KCU2.ORDINAL_POSITION = KCU1.ORDINAL_POSITION

Note:

Information_schema doesn't contain indices (it does find unique-contraints).

So if you want to find foreign-keys based on unique-indices, you need to go over the microsoft proprietary tables:

SELECT  
fksch.name AS FK_CONSTRAINT_SCHEMA
,fk.name AS FK_CONSTRAINT_NAME

,sch1.name AS FK_TABLE_SCHEMA
,t1.name AS FK_TABLE_NAME
,c1.name AS FK_COLUMN_NAME
-- The column_id is not the ordinal, it can be dropped and then there's a gap...
,COLUMNPROPERTY(c1.object_id, c1.name, 'ordinal') AS FK_ORDINAL_POSITION

,COALESCE(pksch.name,sch2.name) AS REFERENCED_CONSTRAINT_SCHEMA
,COALESCE(pk.name, sysi.name) AS REFERENCED_CONSTRAINT_NAME

,sch2.name AS REFERENCED_TABLE_SCHEMA
,t2.name AS REFERENCED_TABLE_NAME
,c2.name AS REFERENCED_COLUMN_NAME
,COLUMNPROPERTY(c2.object_id, c2.name, 'ordinal') AS REFERENCED_ORDINAL_POSITION
FROM sys.foreign_keys AS fk

LEFT JOIN sys.schemas AS fksch
ON fksch.schema_id = fk.schema_id

-- not inner join: unique indices
LEFT JOIN sys.key_constraints AS pk
ON pk.parent_object_id = fk.referenced_object_id
AND pk.unique_index_id = fk.key_index_id

LEFT JOIN sys.schemas AS pksch
ON pksch.schema_id = pk.schema_id

LEFT JOIN sys.indexes AS sysi
ON sysi.object_id = fk.referenced_object_id
AND sysi.index_id = fk.key_index_id

INNER JOIN sys.foreign_key_columns AS fkc
ON fkc.constraint_object_id = fk.object_id

INNER JOIN sys.tables AS t1
ON t1.object_id = fkc.parent_object_id

INNER JOIN sys.schemas AS sch1
ON sch1.schema_id = t1.schema_id

INNER JOIN sys.columns AS c1
ON c1.column_id = fkc.parent_column_id
AND c1.object_id = fkc.parent_object_id

INNER JOIN sys.tables AS t2
ON t2.object_id = fkc.referenced_object_id

INNER JOIN sys.schemas AS sch2
ON sch2.schema_id = t2.schema_id

INNER JOIN sys.columns AS c2
ON c2.column_id = fkc.referenced_column_id
AND c2.object_id = fkc.referenced_object_id

Proof-test for edge-cases:

CREATE TABLE __groups ( grp_id int, grp_name varchar(50), grp_name2 varchar(50) )
ALTER TABLE __groups ADD CONSTRAINT UQ___groups_grp_name2 UNIQUE (grp_name2)
CREATE UNIQUE INDEX IX___groups_grp_name ON __groups(grp_name)

GO
CREATE TABLE __group_mappings( map_id int, map_grp_name varchar(50), map_grp_name2 varchar(50), map_usr_name varchar(50) )
GO

ALTER TABLE __group_mappings ADD CONSTRAINT FK___group_mappings___groups FOREIGN KEY(map_grp_name)
REFERENCES __groups (grp_name)
GO


ALTER TABLE __group_mappings ADD CONSTRAINT FK___group_mappings___groups2 FOREIGN KEY(map_grp_name2)
REFERENCES __groups (grp_name2)
GO


SELECT @@VERSION -- Microsoft SQL Server 2016 (SP1-GDR) (KB4458842)
SELECT version() -- PostgreSQL 9.6.6 on x86_64-pc-linux-gnu
GO

How can I find out what FOREIGN KEY constraint references a table in SQL Server?

Here it is:

SELECT 
OBJECT_NAME(f.parent_object_id) TableName,
COL_NAME(fc.parent_object_id,fc.parent_column_id) ColName
FROM
sys.foreign_keys AS f
INNER JOIN
sys.foreign_key_columns AS fc
ON f.OBJECT_ID = fc.constraint_object_id
INNER JOIN
sys.tables t
ON t.OBJECT_ID = fc.referenced_object_id
WHERE
OBJECT_NAME (f.referenced_object_id) = 'YourTableName'

This way, you'll get the referencing table and column name.

Edited to use sys.tables instead of generic sys.objects as per comment suggestion.
Thanks, marc_s

How to find foreign key dependencies in SQL Server?

The following query will help to get you started. It lists all Foreign Key Relationships within the current database.

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

You can also view relationships graphically within SQL Server Management studio within Database Diagrams.

How can I list all foreign keys referencing a given table in SQL Server?

Not sure why no one suggested but I use sp_fkeys to query foreign keys for a given table:

EXEC sp_fkeys 'TableName'

You can also specify the schema:

EXEC sp_fkeys @pktable_name = 'TableName', @pktable_owner = 'dbo'

Without specifying the schema, the docs state the following:

If pktable_owner is not specified, the default table visibility rules
of the underlying DBMS apply.

In SQL Server, if the current user owns a table with the specified
name, that table's columns are returned. If pktable_owner is not
specified and the current user does not own a table with the specified
pktable_name, the procedure looks for a table with the specified
pktable_name owned by the database owner. If one exists, that table's
columns are returned.

How to find primary keys for all foreign keys in a DB using INFORMATION_SCHEMA

SELECT  ccu1.TABLE_NAME as fkTable, ccu1.COLUMN_NAME as fkColumn, 
ccu2.TABLE_NAME as referencedTable, ccu2.COLUMN_NAME as referencedColumn
FROM INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE ccu1,
INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE ccu2,
INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS rc
WHERE rc.CONSTRAINT_NAME = ccu1.CONSTRAINT_NAME
AND rc.UNIQUE_CONSTRAINT_NAME = ccu2.CONSTRAINT_NAME

I tested this against a SQL Server 2008 database and when run under context of my user database, it returned all my defined tables with foreign keys, and the related table and column.

You can also filter this down further of course.

How to list table foreign keys

You can do this via the information_schema tables. For example:

SELECT
tc.table_schema,
tc.constraint_name,
tc.table_name,
kcu.column_name,
ccu.table_schema AS foreign_table_schema,
ccu.table_name AS foreign_table_name,
ccu.column_name AS foreign_column_name
FROM
information_schema.table_constraints AS tc
JOIN information_schema.key_column_usage AS kcu
ON tc.constraint_name = kcu.constraint_name
AND tc.table_schema = kcu.table_schema
JOIN information_schema.constraint_column_usage AS ccu
ON ccu.constraint_name = tc.constraint_name
AND ccu.table_schema = tc.table_schema
WHERE tc.constraint_type = 'FOREIGN KEY' AND tc.table_name='mytable';

How do I see all foreign keys to a table or column?

For a Table:

SELECT 
TABLE_NAME,COLUMN_NAME,CONSTRAINT_NAME, REFERENCED_TABLE_NAME,REFERENCED_COLUMN_NAME
FROM
INFORMATION_SCHEMA.KEY_COLUMN_USAGE
WHERE
REFERENCED_TABLE_SCHEMA = '' AND
REFERENCED_TABLE_NAME = '';

For a Column:

SELECT 
TABLE_NAME,COLUMN_NAME,CONSTRAINT_NAME, REFERENCED_TABLE_NAME,REFERENCED_COLUMN_NAME
FROM
INFORMATION_SCHEMA.KEY_COLUMN_USAGE
WHERE
REFERENCED_TABLE_SCHEMA = '' AND
REFERENCED_TABLE_NAME = '
' AND
REFERENCED_COLUMN_NAME = '';

Basically, we changed REFERENCED_TABLE_NAME with REFERENCED_COLUMN_NAME in the where clause.

Find all foreign keys constraints in database referencing a certain primary key

Look at How to find foreign key dependencies in SQL Server?

You can sort on PK_Table and PK_Column to get what you want



Related Topics



Leave a reply



Submit