如何从所有表中删除所有约束?

Aar*_*and 33 sql-server constraint ddl

我想从 SQL Server 数据库中的所有表中删除所有默认约束、检查约束、唯一约束、主键和外键。我知道如何从 中获取所有约束名称sys.objects,但是如何填充ALTER TABLE部件?

Aar*_*and 44

您可以通过连接sys.tables.object_id = sys.objects.parent_object_id这些对象类型轻松获取此信息。

DECLARE @sql NVARCHAR(MAX);
SET @sql = N'';

SELECT @sql = @sql + N'
  ALTER TABLE ' + QUOTENAME(s.name) + N'.'
  + QUOTENAME(t.name) + N' DROP CONSTRAINT '
  + QUOTENAME(c.name) + ';'
FROM sys.objects AS c
INNER JOIN sys.tables AS t
ON c.parent_object_id = t.[object_id]
INNER JOIN sys.schemas AS s 
ON t.[schema_id] = s.[schema_id]
WHERE c.[type] IN ('D','C','F','PK','UQ')
ORDER BY c.[type];

PRINT @sql;
--EXEC sys.sp_executesql @sql;
Run Code Online (Sandbox Code Playgroud)

PRINT只是为了观察,而不是复制和粘贴输出(如果你想运行它,这就是注释掉的EXEC目的) - 如果你有很多约束,它可能不会显示整个脚本,因为PRINT仅限于4,000 个字符 (8kb)。在这些情况下,如果您需要验证整个脚本,请参阅此提示以了解在运行之前验证脚本的其他方法。例如:

SELECT CONVERT(xml, @sql);
Run Code Online (Sandbox Code Playgroud)

一旦您对输出感到满意,请取消注释EXEC.

  • 您可能还想确保在主键之前删除外键约束;`ORDER BY (CASE WHEN c.[type] IN ('PK', 'UQ') THEN 1 ELSE 0 END)` (4认同)

小智 7

我从接受的答案开始,并修改了结构以使用 while 循环,而不是在动态 sql 中构建完整的 sql 语句。我更喜欢这个有几个原因。

查询未存储在大@sql 变量中。此实现允许为输出中出于日志记录目的而删除的每个约束进行打印。在我的单元测试中,执行似乎要快一点。

Set NoCount ON

Declare @schemaName varchar(200)
set @schemaName=''
Declare @constraintName varchar(200)
set @constraintName=''
Declare @tableName varchar(200)
set @tableName=''

While exists
(   
    SELECT c.name
    FROM sys.objects AS c
    INNER JOIN sys.tables AS t
    ON c.parent_object_id = t.[object_id]
    INNER JOIN sys.schemas AS s 
    ON t.[schema_id] = s.[schema_id]
    WHERE c.[type] IN ('D','C','F','PK','UQ')
    and t.[name] NOT IN ('__RefactorLog', 'sysdiagrams')
    and c.name > @constraintName
)

Begin   
    -- First get the Constraint
    SELECT 
        @constraintName=min(c.name)
    FROM sys.objects AS c
    INNER JOIN sys.tables AS t
    ON c.parent_object_id = t.[object_id]
    INNER JOIN sys.schemas AS s 
    ON t.[schema_id] = s.[schema_id]
    WHERE c.[type] IN ('D','C','F','PK','UQ')
    and t.[name] NOT IN ('__RefactorLog', 'sysdiagrams')
    and c.name > @constraintName

    -- Then select the Table and Schema associated to the current constraint
    SELECT 
        @tableName = t.name,
        @schemaName = s.name
    FROM sys.objects AS c
    INNER JOIN sys.tables AS t
    ON c.parent_object_id = t.[object_id]
    INNER JOIN sys.schemas AS s 
    ON t.[schema_id] = s.[schema_id]
    WHERE c.name = @constraintName

    -- Then Print to the output and drop the constraint
    Print 'Dropping constraint ' + @constraintName + '...'
    Exec('ALTER TABLE [' + @schemaName + N'].[' + @tableName + N'] DROP CONSTRAINT [' + @constraintName + ']')
End

Set NoCount OFF
Run Code Online (Sandbox Code Playgroud)