如何在SQL Server中检测表是否为FileTable

我正在使用现有的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的数据库上运行此命令会导致类似

的错误
  

第3级第1线第3行3865消息
  对象'FK__DocumentS__paren__3A69DAC6'上的操作被阻止。该对象是Filetable系统定义的对象,不允许用户修改。

     

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

hellokitys 回答:如何在SQL Server中检测表是否为FileTable

您不应为此使用信息架构视图。特别是因为您关心模式。 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。使用像这样的无证程序很少是一个好主意。我还要担心您正在关闭每个表上的所有约束,而不仅仅是关闭的约束。也许相反,您应该捕获所有要从中删除外键的表(在删除它们之前),然后仅对那些表禁用所有约束。

本文链接:https://www.f2er.com/3157084.html

大家都在问