I need to get a list of all foreign keys, which schema/table they belong to, which schema/table they reference, and the name of the column that is referenced. This is what I have so far but the column being returned is not correct. Any ideas?
select distinct
ParentSchema.name as PARENT_SCHEMA_NAME,
ParentTable.name as PARENT_TABLE_NAME,
TheSchema.name as TABLE_SCHEMA,
TheTable.name as TABLE_NAME,
fks.name as KEY_NAME ,
COL_NAME(ParentTable.OBJECT_ID,fkcs.constraint_column_id) as CHILD_COLUMN_NAME
from
sys.foreign_keys fks
inner join
Sys.foreign_key_columns fkcs
on
fks.parent_object_id = fkcs.parent_object_id
inner join
sys.tables TheTable
on
fks.parent_object_id = TheTable.object_id
inner join
sys.tables ParentTable
on
fks.referenced_object_id = ParentTable.object_id
inner join
sys.schemas TheSchema
on
TheTable.schema_id = TheSchema.schema_id
inner join
sys.schemas ParentSchema
on
ParentTable.schema_id = ParentSchema.schema_id
order by
fks.name
I use the following script for getting the information I need related to foreign keys, could be useful for you too:
SELECT KCU1.CONSTRAINT_NAME AS FK_CONSTRAINT_NAME
, KCU1.TABLE_NAME AS FK_TABLE_NAME
, KCU1.COLUMN_NAME AS FK_COLUMN_NAME
, KCU2.CONSTRAINT_NAME AS REFERENCED_CONSTRAINT_NAME
, KCU2.TABLE_NAME AS REFERENCED_TABLE_NAME
, KCU2.COLUMN_NAME AS REFERENCED_COLUMN_NAME
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
WHERE KCU1.TABLE_NAME = 'PurchaseOrders'
For the table PurchaseOrders, in the WideWorldImporters database it shows the following information:
You can check out all the columns included in the information_schema.referential_constraints and
information_schema.key_column_usage and then change the query to fit your needs.
Related
I am having a problem to list all the foreign keys in a database and show the related tables & the fields from each one.
I have tried this query:
SELECT OBJECT_NAME(parent_object_id)
,OBJECT_NAME(referenced_object_id)
,OBJECT_NAME(object_id)
,*
FROM sys.foreign_keys
But this returns just the parent table and field. I need more information. Can anybody help me here?
You can try the below query from the reference also the reference.
-- using sys tables to enumerate foreign keys
-- returns 45 constraint rows
SELECT
f.name constraint_name
,OBJECT_NAME(f.parent_object_id) referencing_table_name
,COL_NAME(fc.parent_object_id, fc.parent_column_id) referencing_column_name
,OBJECT_NAME (f.referenced_object_id) referenced_table_name
,COL_NAME(fc.referenced_object_id, fc.referenced_column_id) referenced_column_name
,delete_referential_action_desc
,update_referential_action_desc
FROM sys.foreign_keys AS f
INNER JOIN sys.foreign_key_columns AS fc
ON f.object_id = fc.constraint_object_id
ORDER BY f.name
-- using INFORMATION_SCHEMA to enumerate foreign keys
-- returns 45 constraint rows
SELECT
C.CONSTRAINT_NAME [constraint_name]
,C.TABLE_NAME [referencing_table_name]
,KCU.COLUMN_NAME [referencing_column_name]
,C2.TABLE_NAME [referenced_table_name]
,KCU2.COLUMN_NAME [referenced_column_name]
,RC.DELETE_RULE delete_referential_action_desc
,RC.UPDATE_RULE update_referential_action_desc
FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS C
INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE KCU
ON C.CONSTRAINT_SCHEMA = KCU.CONSTRAINT_SCHEMA
AND C.CONSTRAINT_NAME = KCU.CONSTRAINT_NAME
INNER JOIN INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS RC
ON C.CONSTRAINT_SCHEMA = RC.CONSTRAINT_SCHEMA
AND C.CONSTRAINT_NAME = RC.CONSTRAINT_NAME
INNER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS C2
ON RC.UNIQUE_CONSTRAINT_SCHEMA = C2.CONSTRAINT_SCHEMA
AND RC.UNIQUE_CONSTRAINT_NAME = C2.CONSTRAINT_NAME
INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE KCU2
ON C2.CONSTRAINT_SCHEMA = KCU2.CONSTRAINT_SCHEMA
AND C2.CONSTRAINT_NAME = KCU2.CONSTRAINT_NAME
AND KCU.ORDINAL_POSITION = KCU2.ORDINAL_POSITION
WHERE C.CONSTRAINT_TYPE = 'FOREIGN KEY'
ORDER BY C.CONSTRAINT_NAME
To answer your (underlying) question, you can find everything you need in the following system tables:
INFORMATION_SCHEMA.KEY_COLUMN_USAGE
INFORMATION_SCHEMA.TABLE_CONSTRAINTS
INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS
Good luck!
How to retrieve primary key,foreign key and unique keys along with their respective column names of a particular schema in the the format described below in postgresql 9.5? I am beginner please help...
Table_name|Primary_key_name|pk_column_name|foreign_key_name|fk_colum_name|unique_key_name|uk_column_name
To see basic table details
SELECT *
FROM information_schema.columns
WHERE table_name = 'yourTableName';
To list out all FORIEN KEY,PRIMARY KEY, UNIQUE KEY constraints
SELECT tc.constraint_name,
tc.constraint_type,
tc.table_name,
kcu.column_name,
tc.is_deferrable,
tc.initially_deferred,
rc.match_option AS match_type,
rc.update_rule AS on_update,
rc.delete_rule AS on_delete,
ccu.table_name AS references_table,
ccu.column_name AS references_field
FROM information_schema.table_constraints tc
LEFT JOIN information_schema.key_column_usage kcu
ON tc.constraint_catalog = kcu.constraint_catalog
AND tc.constraint_schema = kcu.constraint_schema
AND tc.constraint_name = kcu.constraint_name
LEFT JOIN information_schema.referential_constraints rc
ON tc.constraint_catalog = rc.constraint_catalog
AND tc.constraint_schema = rc.constraint_schema
AND tc.constraint_name = rc.constraint_name
LEFT JOIN information_schema.constraint_column_usage ccu
ON rc.unique_constraint_catalog = ccu.constraint_catalog
AND rc.unique_constraint_schema = ccu.constraint_schema
AND rc.unique_constraint_name = ccu.constraint_name
WHERE lower(tc.constraint_type) in ('foreign key')
We have all inherited bad data models. I have a data model where the FK constraint is going to a data type that isn't implicitly castable. For example, I have a VARCHAR reference column (constraintColumn) which has an FK relationship with an INT parent column (constrainedColumn).
SELECT
OBJECT_NAME(fk.constraint_object_id) KeyName
, t.name constrainedTable
, c.name constrainedColumn
, t2.name constraintTable
, c2.name constraintColumn
FROM
sys.foreign_key_columns AS fk
INNER JOIN
sys.tables AS t ON
fk.parent_object_id = t.object_id
INNER JOIN
sys.columns AS c ON
fk.parent_object_id = c.object_id
AND
fk.parent_column_id = c.column_id
INNER JOIN
sys.tables AS t2 ON
fk.referenced_object_id = t2.object_id
INNER JOIN
sys.columns AS c2 ON
fk.referenced_object_id = c2.object_id
AND
fk.constraint_column_id = c2.column_id
ORDER BY
t.name
, c.name;
How can I use sys.types or something else to determine which data types are implicitly castable?
i need list of tableName , columnName ,constraintsType and cascade type in sql server 2008 so i tried below query but cascade type is null
SELECT TB.name AS "TableName",CL.name AS
"ColumnName",KC.type,FK.delete_referential_action,FK.update_referential_action
FROM SYS.key_constraints KC JOIN SYS.tables TB ON
KC.parent_object_id=TB.object_id JOIN SYS.columns CL ON
KC.parent_object_id=CL.object_id LEFT JOIN SYS.foreign_keys FK ON FK.name = KC.name
I believe this is what you are looking for
SELECT
o1.name AS FK_table,
c1.name AS FK_column,
fk.name AS FK_name,
fk.type as FK_TYPE,
pk.name AS PK_name,
pk.type as PK_TYPE,
fk.delete_referential_action_desc AS Delete_Action,
fk.update_referential_action_desc AS Update_Action
FROM sys.objects o1
INNER JOIN sys.foreign_keys fk
ON o1.object_id = fk.parent_object_id
INNER JOIN sys.foreign_key_columns fkc
ON fk.object_id = fkc.constraint_object_id
INNER JOIN sys.columns c1
ON fkc.parent_object_id = c1.object_id
AND fkc.parent_column_id = c1.column_id
INNER JOIN sys.key_constraints pk
ON fk.referenced_object_id = pk.parent_object_id
AND fk.key_index_id = pk.unique_index_id
ORDER BY o1.name, fkc.constraint_column_id
I didn't try out your query as I don't a sql server in front of me but I believe you are missing a DMV and that is why your left join is returning nulls.
I have written a query to find out column names of tables in the database.
SELECT
t.NAME AS TABLEName,
SCHEMA_NAME(schema_id) + '.' + c.name AS ColumnName
FROM
sys.tables t
INNER JOIN sys.columns c
ON c.object_id = t.object_id
WHERE OBJECT_NAME(c.object_id) LIKE '%Message%'
ORDER BY t.NAME
So far I've got the expected result, but whatever column I am looking I want to find out the dependency of column related tables. By executing the above query I am getting table names and column names.
How can I get the column related dependent tables?
Try this:
SELECT KCU1.TABLE_CATALOG,
KCU1.TABLE_SCHEMA,
KCU1.TABLE_NAME,
KCU1.COLUMN_NAME,
KCU2.TABLE_NAME AS REFERENCED_TABLE_NAME,
KCU2.COLUMN_NAME AS REFERENCED_COLUMN_NAME
FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS KCU1
JOIN INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS AS RC
ON KCU1.CONSTRAINT_CATALOG = RC.CONSTRAINT_CATALOG
AND KCU1.CONSTRAINT_SCHEMA = RC.CONSTRAINT_SCHEMA
AND KCU1.CONSTRAINT_NAME = RC.CONSTRAINT_NAME
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
WHERE KCU1.TABLE_NAME LIKE '%Message%'
ORDER BY
KCU1.TABLE_NAME,
KCU1.COLUMN_NAME
This might help. You will however need to tweak it a bit to suit your specific need:
SELECT OBJECT_NAME(referenced_major_id) AS ReferingObject,
(SELECT o.type_Desc FROM sys.objects o
WHERE o.object_id = d.referenced_major_id) AS ReferingObjType,
CASE WHEN referenced_minor_id <> 0 THEN COL_NAME(referenced_major_id, referenced_minor_id)
ELSE '' END AS RefColumnName,
OBJECT_NAME(object_ID) AS ReferencedObject,
(SELECT o.type_Desc FROM sys.objects o
WHERE o.object_id = d.object_id) AS ReferedObjType
fROM sys.sql_dependencies d
If you're looking for all tables/columns that reference a column in the table whose name contains token Message, you can use this:
;WITH PT AS (
SELECT
tc1.TABLE_NAME,
tc2.COLUMN_NAME
FROM
INFORMATION_SCHEMA.TABLE_CONSTRAINTS tc1
JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE tc2
ON tc1.CONSTRAINT_NAME = tc2.CONSTRAINT_NAME
WHERE tc1.CONSTRAINT_TYPE = 'PRIMARY KEY')
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
JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS FK
ON C.CONSTRAINT_NAME = FK.CONSTRAINT_NAME
JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS PK
ON C.UNIQUE_CONSTRAINT_NAME = PK.CONSTRAINT_NAME
JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE CU
ON C.CONSTRAINT_NAME = CU.CONSTRAINT_NAME
JOIN PT
ON PT.TABLE_NAME = PK.TABLE_NAME
WHERE PK.TABLE_NAME LIKE '%Message%'
ORDER BY
FK.TABLE_NAME,
CU.COLUMN_NAME,
PK.TABLE_NAME,
PT.COLUMN_NAME