I have a pretty extensive ETL in place involving a ton of tables. To improve performance and keep the transaction log clean, I recently decided to TRUNCATE a bunch of tables instead of DELETE. Unfortunately, Now, I was unable to truncate data as these tables are a part of foreign key based referential integrity in MS SQL.
No love lost. I started scripting one FK at a time and saving them in two separate files, DROP_FK.sql and RECREATE_FK.sql. After doing about five of them at 11pm, I realized that this was going to be a painful task. A light bulb went off - why not use the system tables; they surely have all of this information stored somewhere!
After a bit of research, I came up with the below query. There are many other queries (probably more robust than mine) out there on the interwebs! Please do your research.
Without further ado, here is my query.
Database: any
Tables: sys.tables
sys.schemas
sys.foreign_keys
sys.columns
sys.foreign_key_columns
DROP CONSTRAINTS
SELECT convert(Varchar(max),'ALTER TABLE ' + SS.NAME + '.[' + ST.NAME + '] DROP CONSTRAINT [' + FK.NAME + ']') as DropFK_Script
INTO #DropFK
FROM SYS.FOREIGN_KEYS FK
INNER JOIN SYS.TABLES ST ON FK.PARENT_OBJECT_ID = ST.OBJECT_ID
INNER JOIN SYS.SCHEMAS SS ON ST.schema_id = SS.schema_id
select * from #dropfk
drop table #dropfk
RECREATE CONSTRAINTS
SELECT convert(Varchar(max),'ALTER TABLE ' + SS_cons.NAME + '.[' + ST_cons.NAME + '] ADD CONSTRAINT [' + FK.NAME + '] FOREIGN KEY([' +
STUFF((SELECT ',' + c.name
-- get all the columns in the constraint table
FROM sys.columns AS c
INNER JOIN sys.foreign_key_columns AS fc ON fc.parent_column_id = c.column_id
AND fc.parent_object_id = c.[object_id]
WHERE fc.constraint_object_id = fk.[object_id]
), 1, 1, N'')
+ ']) REFERENCES [' + SS_REF.name + '].[' + ST_ref.name + ']([' +
STUFF((SELECT ',' + c.name
-- get all the referenced columns
FROM sys.columns AS c
INNER JOIN sys.foreign_key_columns AS fc ON fc.referenced_column_id = c.column_id
AND fc.referenced_object_id = c.[object_id]
WHERE fc.constraint_object_id = fk.[object_id]
), 1, 1, N'')
+ '])' )
as RecreateFK_Script
INTO #RecreateFK
FROM SYS.FOREIGN_KEYS FK
INNER JOIN SYS.TABLES ST_cons ON FK.PARENT_OBJECT_ID = ST_CONS.OBJECT_ID
INNER JOIN SYS.SCHEMAS SS_cons ON ST_CONS.schema_id = SS_cons.schema_id
INNER JOIN SYS.TABLES ST_ref ON FK.referenced_object_id = ST_ref.object_id
INNER JOIN SYS.SCHEMAS SS_ref ON ST_ref.SCHEMA_ID = SS_ref.schema_id
WHERE ST_REF.is_ms_shipped = 0 AND ST_CONS.is_ms_shipped = 0
ORDER BY SS_cons.NAME + '.[' + ST_cons.NAME + ']'
select * from #RecreateFK
drop table #RecreateFK
Credit: I do not have the URL handy, but the best example I found while researching was written by Aron Bertrand.
No love lost. I started scripting one FK at a time and saving them in two separate files, DROP_FK.sql and RECREATE_FK.sql. After doing about five of them at 11pm, I realized that this was going to be a painful task. A light bulb went off - why not use the system tables; they surely have all of this information stored somewhere!
After a bit of research, I came up with the below query. There are many other queries (probably more robust than mine) out there on the interwebs! Please do your research.
Without further ado, here is my query.
Database: any
Tables: sys.tables
sys.schemas
sys.foreign_keys
sys.columns
sys.foreign_key_columns
DROP CONSTRAINTS
SELECT convert(Varchar(max),'ALTER TABLE ' + SS.NAME + '.[' + ST.NAME + '] DROP CONSTRAINT [' + FK.NAME + ']') as DropFK_Script
INTO #DropFK
FROM SYS.FOREIGN_KEYS FK
INNER JOIN SYS.TABLES ST ON FK.PARENT_OBJECT_ID = ST.OBJECT_ID
INNER JOIN SYS.SCHEMAS SS ON ST.schema_id = SS.schema_id
select * from #dropfk
drop table #dropfk
RECREATE CONSTRAINTS
SELECT convert(Varchar(max),'ALTER TABLE ' + SS_cons.NAME + '.[' + ST_cons.NAME + '] ADD CONSTRAINT [' + FK.NAME + '] FOREIGN KEY([' +
STUFF((SELECT ',' + c.name
-- get all the columns in the constraint table
FROM sys.columns AS c
INNER JOIN sys.foreign_key_columns AS fc ON fc.parent_column_id = c.column_id
AND fc.parent_object_id = c.[object_id]
WHERE fc.constraint_object_id = fk.[object_id]
), 1, 1, N'')
+ ']) REFERENCES [' + SS_REF.name + '].[' + ST_ref.name + ']([' +
STUFF((SELECT ',' + c.name
-- get all the referenced columns
FROM sys.columns AS c
INNER JOIN sys.foreign_key_columns AS fc ON fc.referenced_column_id = c.column_id
AND fc.referenced_object_id = c.[object_id]
WHERE fc.constraint_object_id = fk.[object_id]
), 1, 1, N'')
+ '])' )
as RecreateFK_Script
INTO #RecreateFK
FROM SYS.FOREIGN_KEYS FK
INNER JOIN SYS.TABLES ST_cons ON FK.PARENT_OBJECT_ID = ST_CONS.OBJECT_ID
INNER JOIN SYS.SCHEMAS SS_cons ON ST_CONS.schema_id = SS_cons.schema_id
INNER JOIN SYS.TABLES ST_ref ON FK.referenced_object_id = ST_ref.object_id
INNER JOIN SYS.SCHEMAS SS_ref ON ST_ref.SCHEMA_ID = SS_ref.schema_id
WHERE ST_REF.is_ms_shipped = 0 AND ST_CONS.is_ms_shipped = 0
ORDER BY SS_cons.NAME + '.[' + ST_cons.NAME + ']'
select * from #RecreateFK
drop table #RecreateFK
Credit: I do not have the URL handy, but the best example I found while researching was written by Aron Bertrand.
Comments