SQL Script to alter ALL Foreign Keys to add ON DELETE CASCADE

后端 未结 7 1819
轻奢々
轻奢々 2020-12-04 08:21

I have a SQL 2005 database with approx 250 tables.

I want to temporarily enable ON DELETE CASCADE to all of the Foreign Keys so that I can do a bulk delete easily.

7条回答
  •  暗喜
    暗喜 (楼主)
    2020-12-04 09:19

    More Standards compliant solution:

    ;WITH CTE AS 
    (
        SELECT  
             KCU1.CONSTRAINT_NAME AS FK_CONSTRAINT_NAME 
            ,KCU1.TABLE_SCHEMA AS FK_SCHEMA_NAME 
            ,KCU1.TABLE_NAME AS FK_TABLE_NAME 
            ,KCU1.COLUMN_NAME AS FK_COLUMN_NAME 
            ,KCU1.ORDINAL_POSITION AS FK_ORDINAL_POSITION 
            ,KCU2.CONSTRAINT_NAME AS REFERENCED_CONSTRAINT_NAME 
            ,KCU2.TABLE_SCHEMA AS REFERENCED_SCHEMA_NAME 
            ,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 RC 
    
        INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE 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 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 
    )
    
    
    SELECT 
         FK_CONSTRAINT_NAME
        --,FK_SCHEMA_NAME
        --,FK_TABLE_NAME
        --,FK_COLUMN_NAME
        --,FK_ORDINAL_POSITION
        --,REFERENCED_CONSTRAINT_NAME
        --,REFERENCED_SCHEMA_NAME
        --,REFERENCED_TABLE_NAME
        --,REFERENCED_COLUMN_NAME
        --,REFERENCED_ORDINAL_POSITION
    
        ,
            'ALTER TABLE [' + FK_SCHEMA_NAME + ']' 
            + '.[' + FK_TABLE_NAME + '] ' 
            + 'DROP CONSTRAINT [' + FK_CONSTRAINT_NAME + ']; ' 
        AS DropStmt 
    
        ,
        'ALTER TABLE [' + FK_SCHEMA_NAME + ']' 
            + '.[' + FK_TABLE_NAME + '] ' + 
            + 'WITH CHECK ADD CONSTRAINT [' +  FK_CONSTRAINT_NAME + '] ' 
            + 'FOREIGN KEY([' + FK_COLUMN_NAME + ']) ' 
            + 'REFERENCES [' + REFERENCED_SCHEMA_NAME + '].[' + REFERENCED_TABLE_NAME + ']([' + REFERENCED_COLUMN_NAME + ']) ON DELETE CASCADE; ' 
        AS CreateStmt 
    
    FROM CTE 
    
    WHERE (1=1) 
    /*
    AND FK_TABLE_NAME IN 
    (
         'T_SYS_Geschossrechte'
        ,'T_SYS_Gebaeuderechte'
        ,'T_SYS_Standortrechte'
    )
    
    AND REFERENCED_TABLE_NAME NOT LIKE 'T_AP_Ref_Mandant'
    */
    
    ORDER BY  
         FK_TABLE_NAME
        ,FK_CONSTRAINT_NAME
        ,FK_COLUMN_NAME
        ,FK_ORDINAL_POSITION
        ,REFERENCED_CONSTRAINT_NAME
        ,REFERENCED_TABLE_NAME
        ,REFERENCED_COLUMN_NAME
        ,REFERENCED_ORDINAL_POSITION
    

    Edit:
    Extended for multi-column foreign-keys:

    ;WITH CTE AS 
    ( 
      SELECT  
             KCU1.CONSTRAINT_NAME AS FK_CONSTRAINT_NAME 
            ,KCU1.TABLE_SCHEMA AS FK_SCHEMA_NAME 
            ,KCU1.TABLE_NAME AS FK_TABLE_NAME 
            ,KCU1.COLUMN_NAME AS FK_COLUMN_NAME 
            ,KCU1.ORDINAL_POSITION AS FK_ORDINAL_POSITION 
            ,KCU2.CONSTRAINT_NAME AS REFERENCED_CONSTRAINT_NAME 
            ,KCU2.TABLE_SCHEMA AS REFERENCED_SCHEMA_NAME 
            ,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 RC 
    
        INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE 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 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 
    )
    SELECT 
         FK_SCHEMA_NAME
        ,FK_TABLE_NAME
        ,FK_CONSTRAINT_NAME 
        --,FK_COLUMN_NAME
        --,REFERENCED_COLUMN_NAME
    
    
    
        ,
        'ALTER TABLE ' + QUOTENAME(FK_SCHEMA_NAME) + '.' + QUOTENAME(FK_TABLE_NAME) + ' ' 
          + 'DROP CONSTRAINT ' + QUOTENAME(FK_CONSTRAINT_NAME) + '; ' 
        AS DropStmt 
    
        ,
        'ALTER TABLE ' + QUOTENAME(FK_SCHEMA_NAME) + '.' + QUOTENAME(FK_TABLE_NAME) + ' 
        ADD CONSTRAINT ' + QUOTENAME(FK_CONSTRAINT_NAME) + ' 
        FOREIGN KEY('
        + 
            SUBSTRING 
            ( 
                (
                    SELECT ', ' + QUOTENAME(FK.FK_COLUMN_NAME) AS [text()] 
                    FROM CTE AS FK 
                    WHERE FK.FK_CONSTRAINT_NAME = CTE.FK_CONSTRAINT_NAME
                    AND FK.FK_SCHEMA_NAME = CTE.FK_SCHEMA_NAME
                    AND FK.FK_TABLE_NAME = CTE.FK_TABLE_NAME 
                    ORDER BY FK.FK_ORDINAL_POSITION
                    FOR XML PATH, TYPE 
                ).value('.[1]', 'nvarchar(MAX)')
                ,3, 4000
            ) 
        + ') 
    '
        + '    REFERENCES ' + QUOTENAME(REFERENCED_SCHEMA_NAME) + '.' + QUOTENAME(REFERENCED_TABLE_NAME) + '(' 
        + SUBSTRING 
          ( 
              (
                  SELECT ', ' + QUOTENAME(Referenced.REFERENCED_COLUMN_NAME) AS [text()] 
                  FROM CTE AS Referenced 
                  WHERE Referenced.FK_CONSTRAINT_NAME = CTE.FK_CONSTRAINT_NAME
                  AND Referenced.REFERENCED_SCHEMA_NAME = CTE.REFERENCED_SCHEMA_NAME
                  AND Referenced.REFERENCED_TABLE_NAME = CTE.REFERENCED_TABLE_NAME
                  ORDER BY Referenced.REFERENCED_ORDINAL_POSITION 
                  FOR XML PATH, TYPE 
              ).value('.[1]', 'nvarchar(MAX)')
              , 3, 4000 
          )
        + ') 
        ON DELETE CASCADE 
    ; ' AS CreateStmt 
    
    FROM CTE 
    
    GROUP BY 
         FK_SCHEMA_NAME
        ,FK_TABLE_NAME
        ,FK_CONSTRAINT_NAME 
    
        ,REFERENCED_SCHEMA_NAME
        ,REFERENCED_TABLE_NAME
    

    And the far simpler version for PostGreSQL:

    ;WITH CTE AS 
    ( 
      SELECT  
             KCU1.CONSTRAINT_NAME AS FK_CONSTRAINT_NAME 
            ,KCU1.TABLE_SCHEMA AS FK_SCHEMA_NAME 
            ,KCU1.TABLE_NAME AS FK_TABLE_NAME 
            ,KCU1.COLUMN_NAME AS FK_COLUMN_NAME 
            ,KCU1.ORDINAL_POSITION AS FK_ORDINAL_POSITION 
            ,KCU2.CONSTRAINT_NAME AS REFERENCED_CONSTRAINT_NAME 
            ,KCU2.TABLE_SCHEMA AS REFERENCED_SCHEMA_NAME 
            ,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 RC 
    
        INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE 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 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 
    )
    SELECT 
         FK_SCHEMA_NAME
        ,FK_TABLE_NAME
        ,FK_CONSTRAINT_NAME 
        --,FK_COLUMN_NAME
        --,REFERENCED_COLUMN_NAME
    
    
    
        ,
        'ALTER TABLE ' || QUOTE_IDENT(FK_SCHEMA_NAME) || '.' || QUOTE_IDENT(FK_TABLE_NAME) || ' ' 
          || 'DROP CONSTRAINT ' || QUOTE_IDENT(FK_CONSTRAINT_NAME) || '; ' 
        AS DropStmt 
    
        ,
        'ALTER TABLE ' || QUOTE_IDENT(FK_SCHEMA_NAME) || '.' || QUOTE_IDENT(FK_TABLE_NAME) || ' 
        ADD CONSTRAINT ' || QUOTE_IDENT(FK_CONSTRAINT_NAME) || ' 
        FOREIGN KEY(' || string_agg(FK_COLUMN_NAME, ', ') || ') 
    '
        || '    REFERENCES ' || QUOTE_IDENT(REFERENCED_SCHEMA_NAME) || '.' || QUOTE_IDENT(REFERENCED_TABLE_NAME) || '(' || string_agg(REFERENCED_COLUMN_NAME, ', ') || ') 
        ON DELETE CASCADE 
    ; ' AS CreateStmt 
    
    FROM CTE 
    
    GROUP BY 
         FK_SCHEMA_NAME
        ,FK_TABLE_NAME
        ,FK_CONSTRAINT_NAME 
    
        ,REFERENCED_SCHEMA_NAME
        ,REFERENCED_TABLE_NAME
    

提交回复
热议问题