用于更改所有外键以添加 ON DELETE CASCADE 的 SQL 脚本

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/868620/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-01 02:05:11  来源:igfitidea点击:

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

sqlsql-serversql-server-2005

提问by Robin Day

I have a SQL 2005 database with approx 250 tables.

我有一个包含大约 250 个表的 SQL 2005 数据库。

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

我想暂时对所有外键启用 ON DELETE CASCADE,以便我可以轻松地进行批量删除。

I then want to turn off ON DELETE CASCADE on all Foreign Keys.

然后我想关闭所有外键的 ON DELETE CASCADE。

The only way I know of doing this, is to use Management Studio to generate a full database create script, do some kind of search and replace to strip out everything but Foreign Keys, save the script, then do some more search and replacing to add the ON DELETE CASCADE.

我知道这样做的唯一方法是使用 Management Studio 生成完整的数据库创建脚本,进行某种搜索和替换以去除除外键之外的所有内容,保存脚本,然后进行更多搜索和替换以添加删除级联。

Then I run the script, do my delete, and then run the other script.

然后我运行脚本,删除,然后运行另一个脚本。

Is there an easier way to produce this script? This method seems far too prone to error and I will have to keep the script up to date with any other changes we make to the database, or re-generate it manually each time I may need to use it.

有没有更简单的方法来生成这个脚本?这种方法似乎太容易出错,我必须使脚本与我们对数据库所做的任何其他更改保持同步,或者每次我可能需要使用它时手动重新生成它。

Is an alternative option to run a select on the system tables to "generate" the script for me? Could it even be possible to run an update on a system table that enables and disables ON DELETE CASCADE?

是在系统表上运行选择以“生成”脚本的替代选项吗?甚至可以在启用和禁用 ON DELETE CASCADE 的系统表上运行更新吗?

回答by Andomar

Here's a script I used for a similiar purpose. It does not support composite foreign keys (which use more than one field.) And it would probably need some tweaking before it will work for your situation. EDIT: In particular it does not handle multi-column foreign keys correctly.

这是我用于类似目的的脚本。它不支持复合外键(使用多个字段)。它可能需要一些调整才能适合您的情况。 编辑:特别是它不能正确处理多列外键。

select
  DropStmt = 'ALTER TABLE [' + ForeignKeys.ForeignTableSchema + 
      '].[' + ForeignKeys.ForeignTableName + 
      '] DROP CONSTRAINT [' + ForeignKeys.ForeignKeyName + ']; '
,  CreateStmt = 'ALTER TABLE [' + ForeignKeys.ForeignTableSchema + 
      '].[' + ForeignKeys.ForeignTableName + 
      '] WITH CHECK ADD CONSTRAINT [' +  ForeignKeys.ForeignKeyName + 
      '] FOREIGN KEY([' + ForeignKeys.ForeignTableColumn + 
      ']) REFERENCES [' + schema_name(sys.objects.schema_id) + '].[' +
  sys.objects.[name] + ']([' +
  sys.columns.[name] + ']) ON DELETE CASCADE; '
 from sys.objects
  inner join sys.columns
    on (sys.columns.[object_id] = sys.objects.[object_id])
  inner join (
    select sys.foreign_keys.[name] as ForeignKeyName
     ,schema_name(sys.objects.schema_id) as ForeignTableSchema
     ,sys.objects.[name] as ForeignTableName
     ,sys.columns.[name]  as ForeignTableColumn
     ,sys.foreign_keys.referenced_object_id as referenced_object_id
     ,sys.foreign_key_columns.referenced_column_id as referenced_column_id
     from sys.foreign_keys
      inner join sys.foreign_key_columns
        on (sys.foreign_key_columns.constraint_object_id
          = sys.foreign_keys.[object_id])
      inner join sys.objects
        on (sys.objects.[object_id]
          = sys.foreign_keys.parent_object_id)
        inner join sys.columns
          on (sys.columns.[object_id]
            = sys.objects.[object_id])
           and (sys.columns.column_id
            = sys.foreign_key_columns.parent_column_id)
    ) ForeignKeys
    on (ForeignKeys.referenced_object_id = sys.objects.[object_id])
     and (ForeignKeys.referenced_column_id = sys.columns.column_id)
 where (sys.objects.[type] = 'U')
  and (sys.objects.[name] not in ('sysdiagrams'))

回答by Ed Avis

Andomar's answerabove is good but works for single-column foreign key constraints only. I adapted it a little for multi-column constraints:

Andomar上面的答案很好,但仅适用于单列外键约束。我针对多列约束对其进行了一些调整:

create function dbo.fk_columns (@constraint_object_id int)
returns varchar(255)
as begin
declare @r varchar(255)
select @r = coalesce(@r + ',', '') + c.name
from sys.foreign_key_columns fkc
join sys.columns c
  on  fkc.parent_object_id = c.object_id
  and fkc.parent_column_id = c.column_id
where fkc.constraint_object_id = @constraint_object_id
return @r
end

select distinct
  DropStmt = 'ALTER TABLE [' + ForeignKeys.ForeignTableSchema +
      '].[' + ForeignKeys.ForeignTableName +
      '] DROP CONSTRAINT [' + ForeignKeys.ForeignKeyName + '] '
,  CreateStmt = 'ALTER TABLE [' + ForeignKeys.ForeignTableSchema +
  '].[' + ForeignKeys.ForeignTableName +
  '] WITH CHECK ADD CONSTRAINT [' +  ForeignKeys.ForeignKeyName +
  '] FOREIGN KEY(' + dbo.fk_columns(constraint_object_id) + ')' +
  'REFERENCES [' + schema_name(sys.objects.schema_id) + '].[' +
  sys.objects.[name] + '] '
  + ' ON DELETE CASCADE'
 from sys.objects
  inner join sys.columns
    on (sys.columns.[object_id] = sys.objects.[object_id])
  inner join (
select sys.foreign_keys.[name] as ForeignKeyName
 ,schema_name(sys.objects.schema_id) as ForeignTableSchema
 ,sys.objects.[name] as ForeignTableName
 ,sys.columns.[name]  as ForeignTableColumn
 ,sys.foreign_keys.referenced_object_id as referenced_object_id
 ,sys.foreign_key_columns.referenced_column_id as referenced_column_id
 ,sys.foreign_keys.object_id as constraint_object_id
 from sys.foreign_keys
  inner join sys.foreign_key_columns
    on (sys.foreign_key_columns.constraint_object_id
      = sys.foreign_keys.[object_id])
  inner join sys.objects
    on (sys.objects.[object_id]
      = sys.foreign_keys.parent_object_id)
    inner join sys.columns
      on (sys.columns.[object_id]
        = sys.objects.[object_id])
       and (sys.columns.column_id
        = sys.foreign_key_columns.parent_column_id)
-- Uncomment this if you want to include only FKs that already
-- have a cascade constraint.
--       where (delete_referential_action_desc = 'CASCADE' or update_referential_action_desc = 'CASCADE')
) ForeignKeys
on (ForeignKeys.referenced_object_id = sys.objects.[object_id])
 and (ForeignKeys.referenced_column_id = sys.columns.column_id)
 where (sys.objects.[type] = 'U')
  and (sys.objects.[name] not in ('sysdiagrams'))

You can also use the query to help removeON DELETE CASCADEfrom FKs that currently have it.

您还可以使用查询帮助从当前拥有它的 FK 中删除ON DELETE CASCADE

This still doesn't handle the case where the columns are named different things in the two tables - another user-defined function would need to be defined for that.

这仍然不能处理两个表中列被命名为不同事物的情况 - 需要为此定义另一个用户定义的函数。

回答by Stefan Steiger

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:

而 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

回答by SO User

You'll have to to alter the table, drop FK constraints and recreate them:

您必须更改表,删除 FK 约束并重新创建它们:

This is db2 syntax. SQLServer should be similar

这是 db2 语法。SQLServer 应该类似

ALTER TABLE emp DROP CONSTRAINT fk_dept;

ALTER TABLE emp ADD CONSTRAINT fk_dept
FOREIGN KEY(dept_no)
REFERENCES dept(deptno)
ON DELETE CASCADE;

You can write your own sp to query the system table for all the foreign keys, drop them and recreate them. You'll have to use dynamic sql in your sp to do this where you can loop through the fk defn, put them in a varchar and append/edit to include CASCADE and then execute stmt.

您可以编写自己的 sp 来查询系统表中的所有外键,删除它们并重新创建它们。您必须在 sp 中使用动态 sql 来执行此操作,您可以在其中循环 fk defn,将它们放入 varchar 并追加/编辑以包含 CASCADE,然后执行 stmt。

回答by nootn

The answer from @Andomarworked for me but it was a bit manual - you have to run it, then copy the results and run them. I needed to use this as part of my automated test setup so needed it to run in one query automatically.

@Andomar的答案对我有用,但有点手动-您必须运行它,然后复制结果并运行它们。我需要将其用作自动化测试设置的一部分,因此需要它自动在一个查询中运行。

I have come up with the following which gets all the SQL to run in order to modify the foreign key constraints, then actually runs it all in one go:

我想出了以下让所有 SQL 运行以修改外键约束的方法,然后实际上一口气运行它:

    IF Object_id('tempdb..#queriesForContraints') IS NOT NULL 
      BEGIN 
          DROP TABLE #queriesForContraints
      END 

    DECLARE @ignoreTablesCommaSeparated VARCHAR(1000)

    SELECT 'ALTER TABLE [' 
           + ForeignKeys.foreigntableschema + '].[' 
           + ForeignKeys.foreigntablename 
           + '] DROP CONSTRAINT [' 
           + ForeignKeys.foreignkeyname + ']; ' 
           + 'ALTER TABLE [' 
           + ForeignKeys.foreigntableschema + '].[' 
           + ForeignKeys.foreigntablename 
           + '] WITH CHECK ADD CONSTRAINT [' 
           + ForeignKeys.foreignkeyname 
           + '] FOREIGN KEY([' 
           + ForeignKeys.foreigntablecolumn 
           + ']) REFERENCES [' 
           + Schema_name(sys.objects.schema_id) + '].[' 
           + sys.objects.[name] + ']([' 
           + sys.columns.[name] 
           + ']) ON DELETE CASCADE; ' AS query
    INTO #queriesForContraints
    FROM   sys.objects 
           INNER JOIN sys.columns 
                   ON ( sys.columns.[object_id] = sys.objects.[object_id] ) 
           INNER JOIN (SELECT sys.foreign_keys.[name]                      AS 
                              ForeignKeyName, 
                              Schema_name(sys.objects.schema_id)           AS 
                  ForeignTableSchema, 
                              sys.objects.[name]                           AS 
                  ForeignTableName, 
                              sys.columns.[name]                           AS 
                  ForeignTableColumn, 
                              sys.foreign_keys.referenced_object_id        AS 
                  referenced_object_id, 
                              sys.foreign_key_columns.referenced_column_id AS 
                  referenced_column_id 
                       FROM   sys.foreign_keys 
                              INNER JOIN sys.foreign_key_columns 
                                      ON ( 
                              sys.foreign_key_columns.constraint_object_id = 
                              sys.foreign_keys.[object_id] ) 
                              INNER JOIN sys.objects 
                                      ON ( sys.objects.[object_id] = 
                                         sys.foreign_keys.parent_object_id ) 
                              INNER JOIN sys.columns 
                                      ON ( sys.columns.[object_id] = 
                                           sys.objects.[object_id] ) 
                                         AND ( sys.columns.column_id = 
    sys.foreign_key_columns.parent_column_id )) 
    ForeignKeys 
    ON ( ForeignKeys.referenced_object_id = sys.objects.[object_id] ) 
    AND ( ForeignKeys.referenced_column_id = sys.columns.column_id ) 
    WHERE  ( sys.objects.[type] = 'U' ) 
           AND ( sys.objects.[name] NOT IN ( 
                'sysdiagrams' --add more comma separated table names here if required
            ) ) 

    DECLARE @queryToRun NVARCHAR(MAX)

    SELECT  @queryToRun = STUFF(
            (SELECT query + ''
             FROM #queriesForContraints
             FOR XML PATH (''))
         , 1, 0, '')

    EXEC sp_executesql @statement = @queryToRun

    IF Object_id('tempdb..#queriesForContraints') IS NOT NULL 
      BEGIN 
          DROP TABLE #queriesForContraints
      END 

回答by KM.

make a new stored procedure, where the only parameter is the name of the table to process. In that procedure, you'll need to loop over sys.foreign_keys and sys.foreign_key_columns to build the proper drop and create syntax, just use a cursor and some prints (KISS).

创建一个新的存储过程,其中唯一的参数是要处理的表的名称。在该过程中,您需要遍历 sys.foreign_keys 和 sys.foreign_key_columns 以构建正确的 drop 和 create 语法,只需使用光标和一些打印 (KISS)。

call this procedure with the syntax:

使用以下语法调用此过程:

EXEC sp_msforeachtable 'YourProcedureName ''?'''

and it will run for each table. Take and run the output, and you are done.

它将为每个表运行。获取并运行输出,你就完成了。

回答by Gabriel Vaz de Carvalho

A simple solution I found is to export the database to a single file, use the search function to replace all the NO ACTION to CASCADE, drop the database and import the edited file.

我找到的一个简单的解决方案是将数据库导出到单个文件,使用搜索功能将所有 NO ACTION 替换为 CASCADE,删除数据库并导入编辑后的文件。

Information changed on the database between the export and import will be lost.

在导出和导入之间更改的数据库信息将丢失。