为所有表设置IDENTITY_INSERT OFF

m_e*_*sta 35 sql sql-server

我有一个脚本,它创建一个完整的数据库,并将所有记录插入到几十个表中.它工作得很好,除非在处理过程中出现一些问题,并且当一个表在IDATITY_INSERT ON时,当脚本在插入期间失败并且可以再次设置为OFF之前.

发生这种情况时,脚本会在尝试再次运行时自动失败,当我们进入第一个表的插入时,错误"IDENTITY_INSERT已经为表xx打开".

作为故障保护,我想确保在运行安装脚本中的其余处理之前,将所有表的IDENTITY_INSERT设置为OFF.

作为替代方案,我们可以关闭MS SQL连接并再次打开它,据我所知,它将清除连接会话的所有IDENTITY_INSERT值.

什么是最好的方法,并防止"已经开启"的错误?

Joh*_*wey 47

动态SQL:

select 'set identity_insert ['+s.name+'].['+o.name+'] off'
from sys.objects o
inner join sys.schemas s on s.schema_id=o.schema_id
where o.[type]='U'
and exists(select 1 from sys.columns where object_id=o.object_id and is_identity=1)
Run Code Online (Sandbox Code Playgroud)

然后将生成的SQL复制并粘贴到另一个查询窗口并运行


Lyn*_*ing 18

EXEC sp_MSforeachtable @command1="SET IDENTITY_INSERT ? OFF"
Run Code Online (Sandbox Code Playgroud)

  • 我非常喜欢这个...除了,不是这个数据库中的每个表都有一个标识字段,所以这个失败了.否则我怀疑它会是完美的. (3认同)
  • 我知道这不是任务,但我希望对于那些像我一样寻找SET IDENTITY_INSERT ON的人来说,这将是有用的信息. (2认同)

Kev*_*evD 6

EXEC sp_MSforeachtable @command1="PRINT '?'; SET IDENTITY_INSERT ? OFF",
@whereand = ' AND EXISTS (SELECT 1 FROM sys.columns WHERE object_id = o.id  AND is_identity = 1)'
Run Code Online (Sandbox Code Playgroud)

基于Lynn的答案,如果你懒得在多个步骤中执行此操作 - 这应该在所有存在标识列的表上运行.

Caveat仅在2012年进行了测试,sp_MSforeachtable当然完全不受支持......