How to drop all Foreign Key constraints in all tables?

后端 未结 7 1208
难免孤独
难免孤独 2020-12-08 10:03

I want to write sql command to drop all constraints in all tables. I searched on the internet and found the following which works fine if the database is small and not compl

相关标签:
7条回答
  • 2020-12-08 10:38
    CREATE TABLE #Commands (Command VARCHAR(MAX))
    
    INSERT #Commands
    SELECT 'ALTER TABLE ' + QUOTENAME(RC.CONSTRAINT_SCHEMA)
        + '.' + QUOTENAME(KCU1.TABLE_NAME)
        + ' DROP CONSTRAINT ' + QUOTENAME(rc.CONSTRAINT_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
    WHERE ORDINAL_POSITION=1
    
    --SELECT * FROM #Commands
    
    DECLARE @Command VARCHAR(MAX)
    DECLARE curCommand CURSOR FOR
    SELECT Command FROM #Commands
    
    OPEN curCommand
    
    FETCH NEXT FROM curCommand INTO @Command
    
    WHILE @@FETCH_STATUS =0
    BEGIN
    
        EXEC(@Command)
        FETCH NEXT FROM curCommand INTO @Command
    
    END
    
    CLOSE curCommand
    DEALLOCATE curCommand
    
    DROP TABLE #Commands
    
    0 讨论(0)
  • 2020-12-08 10:40

    I have improved the first script provided by @Yaroslav and the script provided by @Quandary so they now works for databases whose SQL query to drop all foreign keys one by one exceeds the size allocated for the SQL variable (4000 or MAX characters).

    The altered scripts drop 5 foreign keys per iteration (just to be safe, implemented by adding TOP 5). The scripts stop when there is no foreign key left to drop (the SQL variable stays empty after running the SELECT).

    First script by @Yaroslav

    DECLARE @SQL varchar(4000)
    IterationStart:
    SET @SQL=''
    SELECT TOP 5 @SQL = @SQL + 'ALTER TABLE ' + FK.TABLE_NAME + ' DROP CONSTRAINT [' + RTRIM(C.CONSTRAINT_NAME) +'];' + CHAR(13)
      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
    IF @SQL <> ''
    BEGIN
      EXEC(@SQL)
      GOTO IterationStart
    END
    

    Script by @Quandary

    DECLARE @sql nvarchar(MAX) 
    
    IterationStart:
    SET @sql = '' 
    
    SELECT TOP 5 @sql = @sql + 'ALTER TABLE ' + QUOTENAME(RC.CONSTRAINT_SCHEMA) 
        + '.' + QUOTENAME(KCU1.TABLE_NAME) 
        + ' DROP CONSTRAINT ' + QUOTENAME(rc.CONSTRAINT_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 
    
    IF @SQL <> ''
    BEGIN
      EXEC(@SQL)
      GOTO IterationStart
    END
    
    0 讨论(0)
  • 2020-12-08 10:40

    Most simple variant:

    DECLARE @sql nvarchar(MAX) 
    SET @sql = N'' 
    
    SELECT @sql = @sql + N'ALTER TABLE ' + QUOTENAME(KCU1.TABLE_SCHEMA) 
        + N'.' + QUOTENAME(KCU1.TABLE_NAME) 
        + N' DROP CONSTRAINT ' -- + QUOTENAME(rc.CONSTRAINT_SCHEMA)  + N'.'  -- not in MS-SQL
        + QUOTENAME(rc.CONSTRAINT_NAME) + N'; ' + CHAR(13) + CHAR(10) 
    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 
    
    
    -- PRINT @sql 
    EXECUTE(@sql) 
    
    0 讨论(0)
  • 2020-12-08 10:44

    Here's a short and sweet script I use (on SQL Server 2008 and up) to remove all foreign keys that also takes into account the object's schema:

    declare @sql varchar(max) = (
        select 
            'alter table ' + quotename(schema_name(schema_id)) + '.' +
            quotename(object_name(parent_object_id)) +
            ' drop constraint '+quotename(name) + ';'
        from sys.foreign_keys
        for xml path('')
    );
    exec sp_executesql @sql;
    
    0 讨论(0)
  • 2020-12-08 10:49

    I used the INFORMATION_SCHEMA solution mentioned by @Yaroslav, but had too many foreign key constants in my database to fit them all into a varchar(MAX). So I had to modify the script to use a temporary table and a cursor instead.

    Also, I added [] around the table name.

    DECLARE @SQL TABLE (Command VARCHAR(MAX))
    
    INSERT @SQL
    SELECT 'ALTER TABLE [' + FK.TABLE_NAME + '] DROP CONSTRAINT [' + RTRIM(C.CONSTRAINT_NAME) +'];' + CHAR(13)
      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
    
    DECLARE cmdCursor CURSOR
        FOR SELECT Command FROM @SQL
    OPEN cmdCursor
    DECLARE @Command VARCHAR(MAX)
    
    FETCH NEXT FROM cmdCursor INTO @Command
    WHILE @@FETCH_STATUS = 0
    BEGIN
        PRINT @Command
        EXEC (@Command)
        FETCH NEXT FROM cmdCursor INTO @Command
    END
    
    CLOSE cmdCursor;
    DEALLOCATE cmdCursor;
    
    0 讨论(0)
  • 2020-12-08 10:53

    See Pinal's answer from this link, it is very helpful

    https://blog.sqlauthority.com/2014/04/11/sql-server-drop-all-the-foreign-key-constraint-in-database-create-all-the-foreign-key-constraint-in-database/

    SET NOCOUNT ON
    DECLARE @table TABLE(
    RowId INT PRIMARY KEY IDENTITY(1, 1),
    ForeignKeyConstraintName NVARCHAR(200),
    ForeignKeyConstraintTableSchema NVARCHAR(200),
    ForeignKeyConstraintTableName NVARCHAR(200),
    ForeignKeyConstraintColumnName NVARCHAR(200),
    PrimaryKeyConstraintName NVARCHAR(200),
    PrimaryKeyConstraintTableSchema NVARCHAR(200),
    PrimaryKeyConstraintTableName NVARCHAR(200),
    PrimaryKeyConstraintColumnName NVARCHAR(200)
    )
    INSERT INTO @table(ForeignKeyConstraintName, ForeignKeyConstraintTableSchema, ForeignKeyConstraintTableName, ForeignKeyConstraintColumnName)
    SELECT
    U.CONSTRAINT_NAME,
    U.TABLE_SCHEMA,
    U.TABLE_NAME,
    U.COLUMN_NAME
    FROM
    INFORMATION_SCHEMA.KEY_COLUMN_USAGE U
    INNER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS C
    ON U.CONSTRAINT_NAME = C.CONSTRAINT_NAME
    WHERE
    C.CONSTRAINT_TYPE = 'FOREIGN KEY'
    UPDATE @table SET
    PrimaryKeyConstraintName = UNIQUE_CONSTRAINT_NAME
    FROM
    @table T
    INNER JOIN INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS R
    ON T.ForeignKeyConstraintName = R.CONSTRAINT_NAME
    UPDATE @table SET
    PrimaryKeyConstraintTableSchema = TABLE_SCHEMA,
    PrimaryKeyConstraintTableName = TABLE_NAME
    FROM @table T
    INNER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS C
    ON T.PrimaryKeyConstraintName = C.CONSTRAINT_NAME
    UPDATE @table SET
    PrimaryKeyConstraintColumnName = COLUMN_NAME
    FROM @table T
    INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE U
    ON T.PrimaryKeyConstraintName = U.CONSTRAINT_NAME
    --SELECT * FROM @table
    --DROP CONSTRAINT:
    SELECT
    '
    ALTER TABLE [' + ForeignKeyConstraintTableSchema + '].[' + ForeignKeyConstraintTableName + ']
    DROP CONSTRAINT [' + ForeignKeyConstraintName + ']
    
    GO'
    FROM
    @table
    
    0 讨论(0)
提交回复
热议问题