Thursday, 6 June 2013

A better solution to drop/recreate FK

--
-- step 1:
-- drop all FKs
-- warning: before running scripts, make sure save the scripts from step 3!!!
  SELECT    'ALTER TABLE '
   + s.name + '.' + OBJECT_NAME(fk.parent_object_id)       
   + ' DROP CONSTRAINT ' + fk.NAME + ' ;' AS DropStatement
  FROM sys.foreign_keys fk
    INNER JOIN sys.tables t ON fk.parent_object_id = t.object_id
    INNER JOIN sys.schemas s ON fk.schema_id = s.schema_id

--
-- (optional)
-- step 2: truncte ALL tabls
 SELECT 'TRUNCATE TABLE '+s.name+'.'+t.name as 'TruncateStatement'
    FROM sys.tables t inner join sys.schemas s
   on t.schema_id=s.schema_id
   WHERE t.type='U'
  ORDER BY s.name, t.name

--
-- step 3, recreate FKs with original CHEK option
PRINT N'-- Re-CREATE FOREIGN KEY CONSTRAINTS with original check option --';
SET NOCOUNT ON;
SELECT '
 PRINT N''Creating '+ const.const_name +'...''
 GO
 ALTER TABLE ' + const.parent_obj
  -- you can remove this line if you don't want to keep original check option
  + ' WITH '+CASE WHEN ObjectProperty(const.constid,'CnstIsDisabled') =0 THEN 'CHECK' ELSE 'NOCHECK' END +
  + ' ADD CONSTRAINT ' + const.const_name + ' FOREIGN KEY (
    ' + const.parent_col_csv + '
    ) REFERENCES ' + const.ref_obj + '(' + const.ref_col_csv + ')
 GO' as StatementToReCreateFK
FROM (
    SELECT QUOTENAME(fk.NAME) AS [const_name]
        ,QUOTENAME(schParent.NAME) + '.' + QUOTENAME(OBJECT_name(fkc.parent_object_id)) AS [parent_obj]
        ,STUFF((
                SELECT ',' + QUOTENAME(COL_NAME(fcP.parent_object_id, fcp.parent_column_id))
                FROM sys.foreign_key_columns AS fcP
                WHERE fcp.constraint_object_id = fk.object_id
                FOR XML path('')
                ), 1, 1, '') AS [parent_col_csv]
        ,QUOTENAME(schRef.NAME) + '.' + QUOTENAME(OBJECT_NAME(fkc.referenced_object_id)) AS [ref_obj]
        ,STUFF((
                SELECT ',' + QUOTENAME(COL_NAME(fcR.referenced_object_id, fcR.referenced_column_id))
                FROM sys.foreign_key_columns AS fcR
                WHERE fcR.constraint_object_id = fk.object_id
                FOR XML path('')
                ), 1, 1, '') AS [ref_col_csv]
  ,sfk.constid
    FROM sys.foreign_key_columns AS fkc
    INNER JOIN sys.foreign_keys AS fk ON fk.object_id = fkc.constraint_object_id
    INNER JOIN sys.objects AS oParent ON oParent.object_id = fkc.parent_object_id
    INNER JOIN sys.schemas AS schParent ON schParent.schema_id = oParent.schema_id
    INNER JOIN sys.objects AS oRef ON oRef.object_id = fkc.referenced_object_id
    INNER JOIN sys.schemas AS schRef ON schRef.schema_id = oRef.schema_id
 -- add this to check FK CHECK option
 INNER JOIN sysobjects o on o.name=fk.name
 INNER JOIN sysforeignkeys sfk ON sfk.constid=o.id
    GROUP BY fkc.parent_object_id
        ,fkc.referenced_object_id
        ,fk.NAME
        ,fk.object_id
        ,schParent.NAME
        ,schRef.NAME
  ,sfk.constid
    ) AS const
ORDER BY const.const_name

No comments:

Post a Comment