【问题标题】:How to detect if a table is a FileTable in SQL Server如何在 SQL Server 中检测表是否为 FileTable
【发布时间】:2019-11-05 18:59:35
【问题描述】:

我正在使用现有的 SQL 脚本,该脚本会从数据库中删除所有外键。如果其中一张表是FileTable,则会遇到麻烦。

主要问题:有没有办法检测特定表是FILETABLE 并跳过删除该表上的外键?

如果可能的话:是否也可以通过区分系统外键和自定义外键来获得更细化并从FILETABLE 中删除任何非系统生成的外键?

DECLARE @fkdel varchar(512);

DECLARE FkCrsr CURSOR FOR 
     SELECT 'ALTER TABLE [' + TABLE_SCHEMA + '].[' + TABLE_NAME + '] DROP CONSTRAINT [' + CONSTRAINT_NAME +']' 
     FROM information_schema.table_constraints WITH (NOLOCK)
     WHERE CONSTRAINT_TYPE = 'FOREIGN KEY';

OPEN FkCrsr;

FETCH NEXT FROM FkCrsr INTO @fkdel;

WHILE @@FETCH_STATUS = 0
BEGIN;
    PRINT @fkdel;
    EXEC (@fkdel);

    FETCH NEXT FROM FkCrsr INTO @fkdel;
END;

CLOSE FkCrsr;
DEALLOCATE FkCrsr;

EXEC sp_msforeachtable "ALTER TABLE ? NOCHECK CONSTRAINT all";

在包含 FileTable 的数据库上运行它会导致类似

的错误

消息 3865,第 16 级,状态 1,第 3 行
对象“FK__DocumentS__paren__3A69DAC6”的操作被阻止。该对象是 FileTable 系统定义的对象,不允许用户修改。

消息 3727,第 16 级,状态 0,第 3 行
无法删除约束。查看以前的错误。

【问题讨论】:

    标签: sql-server database tsql foreign-keys filetable


    【解决方案1】:

    您不应该为此使用信息架构视图。特别是因为您关心架构。 MS 文档甚至声明不要使用它。 https://docs.microsoft.com/en-us/sql/relational-databases/system-information-schema-views/table-constraints-transact-sql?view=sql-server-ver15

    如果您改为使用系统视图,这会变得简单得多。例如 sys.tables 有一个列“is_filetable”。 https://docs.microsoft.com/en-us/sql/relational-databases/system-catalog-views/sys-tables-transact-sql?view=sql-server-ver15 另请注意,我在这里使用的是 QUOTENAME 而不是手动添加方括号。

    然后您可以查询 sys.foreign_keys 以查找所有外键,因为这是您唯一关心的约束类型。

    你的整个循环结构可以简化成这样的。

    declare @SQL nvarchar(max) = ''
    
    select @SQL = @SQL + 'ALTER TABLE ' + QUOTENAME(s.name) + '.' + QUOTENAME(t.name) + ' DROP CONSTRAINT ' + QUOTENAME(fk.name) + ';'
    from sys.foreign_keys fk
    join sys.tables t on t.object_id = fk.parent_object_id
    join sys.schemas s on s.schema_id = t.schema_id
    where t.is_filetable = 0
    
    select @SQL
    
    --uncomment the line below to execute your dynamic sql
    --exec sp_executesql @SQL
    

    这会将我们带到 sp_msforeachtable。像这样使用未记录的程序很少是一个好主意。我也会有点紧张,因为您要关闭每张表上的所有约束,而不仅仅是您删除的那些。也许您应该捕获所有要从中删除外键的表(在删除它们之前),然后仅禁用这些表上的所有约束。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-13
      相关资源
      最近更新 更多