使用 IDENTITY_INSERT 时身份种子增加

Pet*_*ell 1 sql-server identity

在 SQL Server 2008 上运行此代码段会产生与在 SQL Server 2014 上不同的结果。我需要它们产生相同的结果。

我的场景是我正在编写单元测试(使用 tsqlt),而这段代码是我试图测试的一个巨大过程的一部分。在我的测试代码中,我可以做任何事情,因为该代码永远不会投入生产。这个“错误”在生产中不会造成损害,但在编写测试时给我带来了问题。意思是,我不想更改代码,只想更改测试。

我的本地开发环境是 SQL Server 2014,但我们的一些 CI 环境仍然是 SQL Server 2008。

  • 我的第一个问题是是否有任何方法可以避免 2008 年出现此(错误)?
  • 我的第二个问题是,是否有任何方法可以使 2014 年的行为与 2008 年相同,从而使测试在 2008 年和 2014 年都通过。任何设置或跟踪标志或黑客?

我目前的技巧是在服务器是 2008 的情况下将表重新设置为 0(而不是 1)。我不喜欢这样,因为当我们的环境升级时我需要更改它或删除它。

IF CHARINDEX('2008', @@VERSION) > 0 BEGIN
        -- HACK to fix identity bug in SQL 2008.
        DBCC CHECKIDENT('...peter', RESEED, 0);
END
Run Code Online (Sandbox Code Playgroud)

麻烦的代码:

IF OBJECT_ID('tempdb..#peter') IS NOT NULL DROP TABLE #peter;
CREATE TABLE #peter(ID INT IDENTITY(1, 1), VALUE CHAR(10));

SET IDENTITY_INSERT #peter ON;
INSERT INTO #peter( ID, VALUE )
VALUES  ( -1,'Thing' ); -- Explicit negative ID value inserted here
SET IDENTITY_INSERT #peter Off;

INSERT INTO #peter( VALUE )
VALUES  ( 'Stuff' );

SELECT * FROM #peter;
Run Code Online (Sandbox Code Playgroud)

SQL Server 2014 中的结果:

2014年

SQL Server 2008:

2008年

服务器版本:

Microsoft SQL Server 2008 (SP4)  
Microsoft SQL Server 2014 
Run Code Online (Sandbox Code Playgroud)

Aar*_*and 6

这是在 Connect 上报告并作为“设计使然”关闭的已知行为更改。您会注意到 2008 年和 2014 年的文档略有不同,部分原因是为了反映DBCC CHECKIDENT()2008 年2014 年)等命令的输出更好地反映了现实。

您现在使用的解决方法和我能想到的一样好,因为没有神奇的跟踪标志来更改任一版本的行为。在我看来,您将测试的优先级置于代码之上似乎很奇怪。您应该进行测试,以便他们可以解释所有代码路径,而不是更改代码以匹配测试期望的输出。我想知道为什么测试甚至关心数据库生成的代理 ID 值,因为您不应该恕我直言。这些应该对用户不可见,并且仅用于参照完整性。