如何在SQL Server中检查IDENTITY_INSERT是否设置为ON或OFF?

Pan*_*sis 68 sql sql-server identity-insert

我已经搜索过这个,但是看起来很容易得到那些不理解这个问题的人的答案.

采用以下语法:

SET IDENTITY_INSERT Table1 ON
Run Code Online (Sandbox Code Playgroud)

你怎么做更像这样的事情:

GET IDENTITY_INSERT Table1
Run Code Online (Sandbox Code Playgroud)

我不想对数据库中的数据或设置做任何事情以获取此信息.谢谢!

Eon*_*Eon 33

由于SET IDENTITY_INSERT会话敏感,因此它在缓冲级别进行管理而不存储在某处.这意味着我们不需要检查IDENTITY_INSERT状态,因为我们从未在当前会话中使用此关键字.

对不起,对此没有帮助.

虽然很好的问题:)

来源:这里

更新 有一些方法可能会这样做,也可以在我链接的网站上看到,IMO,它是太努力有用.

if

(select max(id) from MyTable) < (select max(id) from inserted)

--Then you may be inserting a record normally

BEGIN
    set @I = 1 --SQL wants something to happen in the "IF" side of an IF/ELSE
END

ELSE --You definitely have IDENTITY_INSERT on.  Done as ELSE instead of the other way around so that if there is no inserted table, it will run anyway


BEGIN
.... Code that shouldn't run with IDENTITY_INSERT on
END
Run Code Online (Sandbox Code Playgroud)


Lor*_*uer 19

综上所述:

  • 内森的解决方案是最快的:

    SELECT OBJECTPROPERTY(OBJECT_ID('MyTable'), 'TableHasIdentity');
    
    Run Code Online (Sandbox Code Playgroud)
    • 使用API​​包装器时,可以将整个检查减少到只检查行.例如,当使用C#的SqlDataReaders 属性HasRows和查询构造时,如:

      SELECT CASE OBJECTPROPERTY(OBJECT_ID('MyTable'), 'TableHasIdentity')
             WHEN 1 THEN '1' ELSE NULL END
      
      Run Code Online (Sandbox Code Playgroud)
  • 里卡多的解决方案允许更大的灵活性,但需要Column的身份名称

    SELECT * FROM sys.columns WHERE object_id = OBJECT_ID('MyTable', 'U') 
                            AND name = 'MyTableIdentityColumnName';
    
    Run Code Online (Sandbox Code Playgroud)
  • Bogdan Bodanov解决方案,使用try/ catch也可以工作,但是额外的检查应该将异常处理限制在案例中 IDENTITY_INSERT is already ON for table 'MyTable'. Cannot perform SET operation for table 'MyTable';

  • 非解决方案不可能是最快的——内森和里卡多的解决方案都没有真正解决问题。它们测试标识列是否存在,而不是测试当前会话中该列的 IDENTITY_INSERT 是否打开或关闭。 (8认同)

jmo*_*eno 7

您可以使用下面的代码来查找identity_insert是否打开以及对于哪个表是打开的。

declare @tableWithIdentity varchar(max) = '';
SET IDENTITY_INSERT ExampleTable ON

begin try
  create table #identityCheck (id int identity(1,1))
  SET IDENTITY_INSERT #identityCheck ON
  drop table #identityCheck
end try
begin catch
  declare @msg varchar(max) = error_message()
  set @tableWithIdentity= @msg;
  set @tableWithIdentity = 
  SUBSTRING(@tableWithIdentity,charindex('''',@tableWithIdentity,1)+1, 10000)

  set @tableWithIdentity = SUBSTRING(@tableWithIdentity,1, charindex('''',@tableWithIdentity,1)-1)

  print @msg;
  drop table #identityCheck
end catch

if @tableWithIdentity<>''
begin
  print ('Name of table with Identity_Insert set to ON: ' + @tableWithIdentity)
end
else
begin
  print 'No table currently has Identity Insert Set to ON'
end 
Run Code Online (Sandbox Code Playgroud)


小智 6

如果您尝试为其他某些表关闭IDENTITY_INSERT以避免在您要设置IDENTITY_INSERT时出现错误,则以下内容也适用于您.正如其他人在此主题中所说,IDENTITY_INSERT是一个没有直接可见性的会话设置.但是我做了一个有趣的发现,SET IDENTITY_INSERT OFF对于任何具有标识的表都不会出错,无论该表的IDENTITY_INSERT是否为ON.所以我想到我可以为数据库中具有标识的每个表调用SET IDENTITY_INSERT ... OFF.感觉有点像蛮力解决方案,但我发现以下动态SQL块非常好地完成了这个技巧.

---- make sure IDENTITY_INSERT is OFF ----
DECLARE @cmd NVARCHAR(MAX)
SET @cmd = CAST((SELECT 'SET IDENTITY_INSERT ' + 
             QUOTENAME(OBJECT_SCHEMA_NAME(t.object_id)) + '.' + 
             QUOTENAME(t.name) + ' OFF' + CHAR(10)
             FROM sys.columns c 
             JOIN sys.tables t ON t.object_id = c.object_id
             WHERE c.is_identity = 1 
             ORDER BY 1 FOR XML PATH('')) AS NVARCHAR(MAX))
EXEC sp_executesql @cmd
Run Code Online (Sandbox Code Playgroud)