如何在不知道其表的情况下删除约束?

Posted

技术标签:

【中文标题】如何在不知道其表的情况下删除约束?【英文标题】:How to drop a constraint without knowing its table? 【发布时间】:2015-03-22 19:53:18 【问题描述】:

我想删除 SQL Server 数据库中的每个用户对象,但保留表及其记录不变。但我也想放弃它的限制。所以我创建了这个查询来获取我将粘贴到 SMSS 中并在之后执行的丢弃声明:

SELECT
    'DROP ' +
    CASE 
        WHEN [sys].[all_objects].type IN ('AF','FN','FS','FT','IF','TF') THEN 'FUNCTION '
        WHEN [sys].[all_objects].type IN ('D','C','F','PK','UQ') THEN 'CONSTRAINT '
        WHEN [sys].[all_objects].type IN ('IT','S','U') THEN 'TABLE '
        WHEN [sys].[all_objects].type IN ('P','PC','RF','X') THEN 'PROCEDURE '
        WHEN [sys].[all_objects].type IN ('TA','TR') THEN 'TRIGGER '
        WHEN [sys].[all_objects].type = 'R' THEN 'RULE '
        WHEN [sys].[all_objects].type = 'SN' THEN 'SYNONYM '
        WHEN [sys].[all_objects].type = 'TT' THEN 'TYPE '
        WHEN [sys].[all_objects].type = 'V' THEN 'VIEW '
    END +
    SCHEMA_NAME(sys.[all_objects].[schema_id]) + '.' + OBJECT_NAME(object_id) + '; ', OBJECT_NAME(object_id), [sys].[all_objects].[type_desc], [sys].[all_objects].[type], SCHEMA_NAME(sys.[all_objects].[schema_id])
FROM 
    sys.[all_objects] WITH (NOLOCK) -- WHERE (OBJECT_DEFINITION(object_id) LIKE '%' + @toDrop + '%') AND ([sys].[all_objects].[name] <> @toDrop);
WHERE
    (SCHEMA_NAME(sys.[all_objects].[schema_id]) <> 'sys') AND
    (SCHEMA_NAME(sys.[all_objects].[schema_id]) <> 'INFORMATION_SCHEMA') AND
    ([sys].[all_objects].[type_desc] <> 'USER_TABLE')
ORDER BY
    [sys].[all_objects].[type_desc], SCHEMA_NAME(sys.[all_objects].[schema_id]), OBJECT_NAME(object_id)

问题是,在约束情况下我必须使用ALTER TABLE x DROP CONSTRAINT y

那么如何轻松消除所有约束呢?

【问题讨论】:

你必须有条件逻辑,因为模式前缀也不会用于这些语句(好吧,它会在不同的地方)。您可以通过在sys.objects.parent_object_id 上加入sys.tables 来获取父表名称(为什么,为什么,为什么要使用sys.all_objects?)。 @AaronBertrand 因为我想删除除了表格之外的所有内容。我想做一个数据库迁移,但是我发现的所有工具都无能为力。 sys.all_objects 基本上是您的对象和系统对象的联合。你有针对sys.all_objects 的过滤器,它基本上做同样的事情。所以只需使用sys.objects。另外,考虑使用别名来提高可读性,如果您不想删除表,为什么您的 CASE 表达式明确具有DROP TABLE 的选项?而且您知道您不能删除内部或系统表,对,那为什么它们也在那里? 好的,我会的。谢谢 dba.stackexchange.com/questions/90033/… 【参考方案1】:
    SELECT
        'ALTER TABLE ' + 
        SCHEMA_NAME(sys.[objects].[schema_id]) + '.' + OBJECT_NAME([sys].[objects].[parent_object_id]) +
        ' DROP CONSTRAINT ' +
        OBJECT_NAME(object_id) + '; ', OBJECT_NAME(object_id), [sys].[objects].[type_desc], [sys].[objects].[type], SCHEMA_NAME(sys.[objects].[schema_id]),
        OBJECT_NAME([sys].[objects].[parent_object_id])
    FROM 
        sys.[objects] WITH (NOLOCK) 
    WHERE
        (SCHEMA_NAME(sys.[objects].[schema_id]) <> 'sys') AND
        ([sys].[objects].[type_desc] <> 'USER_TABLE') AND
        ([sys].[objects].TYPE IN ('D','C','F','PK','UQ')) AND
    ORDER BY
        [sys].[objects].[type_desc], SCHEMA_NAME(sys.[objects].[schema_id]), OBJECT_NAME(object_id)
GO

【讨论】:

您似乎很喜欢OBJECT_NAME/SCHEMA_NAME 函数。恕我直言,加入更好。请阅读:blogs.sqlsentry.com/aaronbertrand/…

以上是关于如何在不知道其表的情况下删除约束?的主要内容,如果未能解决你的问题,请参考以下文章

如何在不删除数据库的情况下删除 phpMyAdmin 中数据库中所有表的内容?

psql - 如何在不删除表的情况下刷新数据库内容

如何在不删除或移动mysql中的表的情况下重命名数据库? [复制]

如何在不将实例模型添加到数据库的情况下向实体模型添加FK约束?

oracle数据库表空间占用太大,如何在不删除表的情况下缩小占用空间

如何在不复制数据的情况下创建 Oracle 表的副本?