自动递增SQL值

时间:2017-07-26 06:40:19

标签: sql sql-server stored-procedures sql-server-2008-r2 table-valued-parameters

在我正在工作的公司的全球DBA的智慧中,他现在创建了一个表,它将int作为ID字段,但不会自动增加数字。

我从.Net传递一个表值参数,因为它有大约100行或更多行的数据在任何时候都被传递出来,我不想杀死应用程序,锤击网络或SQL Server。

所以这是我的存储过程

CREATE PROCEDURE sp_Insert_Supporting_Error_Info

(@tvp [dbo].udt_CEQZW READONLY)

as
begin

INSERT INTO CEQZW 
ERROR_VAR_ID, 
ERROR_ID, 
ERROR_VAR_TYPE_CD, 
ERROR_VAR_VALUE) 
SELECT (SELECT coalesce(MAX(ERROR_VAR_ID), 0) + row_number() over (order by 
(select NULL)) FROM CEQZW) as ERROR_VAR_ID, 
ERROR_ID, 
ERROR_VAR_TYPE_CD, 
ERROR_VAR_VALUE FROM @TVP
end
go

我希望这个SELECT coalesce(MAX(ERROR_VAR_ID), 0) + row_number() over (order by (select NULL)) FROM CEQZW会对我有什么把戏,就像我用这个测试一样

declare @p3 dbo.udt_CEQZW
insert into @p3 values(1,N'es',N'test')
insert into @p3 values(1,N'ec',N'test')
insert into @p3 values(1,N'ec',N'test')
insert into @p3 values(1,N'ses',N'test')
insert into @p3 values(1,N'es',N'test')

exec sp_Insert_Supporting_Error_Info @p3

这就是我回来的原因

  

(1行受影响)

     

(1行受影响)

     

(1行受影响)

     

(1行受影响)

     

(1行(s)受影响)   消息2627,级别14,状态1,过程sp_Insert_Supporting_Error_Info,第9行   违反PRIMARY KEY约束' PK_CEQZW'。无法在对象' dbo.CEQZW'中插入重复键。重复键值为(1)。   声明已经终止。

所以我的问题是,除了锤击网络,应用程序和SQL Server自动增量并将ID添加到表中之外,我将如何才能获得

1 个答案:

答案 0 :(得分:2)

好吧,我会先去找你的DBA,然后问他为什么不决定ID列和身份。也许他会改变主意。

但是,如果他保留此决定,请不要尝试自行创建自动增量机制 99.9%的案例有可能失败,特别是在多用户环境中 相反,使用标识列的已内置线程安全方法。

由于我们在讨论的情况是您无法直接在目标表中使用标识列,因此我建议您使用2012版本中引入的序列对象的简单模拟来获取自动增量。 / p>

为此,您需要一个计数(数字)表。如果您的DBA尚未创建一个,请发送给他阅读Jeff Moden的The "Numbers" or "Tally" Table: What it is and how it replaces a loop,然后将他发送给KM。在this SO post上回答创建脚本。 (方法7是我最喜欢的。)

现在你有了一个数字表,你可以添加一个非常简单的表:

CREATE TABLE tblSequence
(
    Value int identity(1,1)
)

然后,您创建一个存储过程,该行将在此表中插入任意数量的行并返回新创建的值(感谢Martin Smith在this post上的合并技巧!):

CREATE PROCEDURE stp_GetNextValues
(
    @NumberOfValues as int
)
AS

    MERGE INTO Sequence
    USING (SELECT Number
           FROM   Tally
           WHERE  Number <= @NumberOfValues) T
    ON 1 = 0
    WHEN NOT MATCHED THEN
      INSERT
      DEFAULT VALUES
    OUTPUT INSERTED.Value; 

GO

然后,无论何时执行此存储过程,您都将获得安全的自动递增值。

EXEC stp_GetNextValues 125

You can see the full script in action on rextester.

我将此归结为您将其纳入您自己的程序。