自动递增 SQL 值
Auto Increment SQL Value
在我现在工作的一家公司的全球 DBA 的无穷智慧中,他创建了一个 table,它将 int 作为 ID 字段,但不会自动递增数字。
我正在传递一个来自 .Net 的 table 值参数,因为它有大约 100 行或更多行的数据在任何时候传递,我不想终止应用程序,锤击网络或 SQL 服务器。
所以这是我的存储过程
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 row(s) affected)
(1 row(s) affected)
(1 row(s) affected)
(1 row(s) affected)
(1 row(s) affected)
Msg 2627, Level 14, State 1, Procedure sp_Insert_Supporting_Error_Info, Line 9
Violation of PRIMARY KEY constraint 'PK_CEQZW'. Cannot insert duplicate key in object 'dbo.CEQZW'. The duplicate key value is (1).
The statement has been terminated.
所以我的问题是,除了破坏网络,应用程序和 SQL 服务器自动递增并将 ID 添加到 table
好吧,我首先要去找你的 DBA,问问他为什么决定不制作 ID 列和标识。也许他会改变主意。
但是,如果他会保留这个决定,请不要尝试自己创建自动递增机制。
99.9% 的情况它都有可能失败,尤其是在多用户环境中。
相反,使用标识列的已经内置的线程安全方法。
由于我们讨论的是不能直接在目标中使用身份列的情况 table,我建议使用 2012 版本中引入的序列对象的简单模拟来获得您的自动递增。
为此,您需要一个计数(数字)table。如果您的 DBA 尚未创建一个,请让他阅读 Jeff Moden 的 The "Numbers" or "Tally" Table: What it is and how it replaces a loop and then send him to KM.'s answer on this SO post 以获取创建脚本。 (方法 7 是我最喜欢的。)
现在你有一个数字 table,你添加一个非常简单的 table:
CREATE TABLE tblSequence
(
Value int identity(1,1)
)
然后,您创建一个存储过程,它将向这个 table 和 returns 新创建的值中插入任意数量的行(感谢 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.
我将其纳入您自己的程序由您决定。
在我现在工作的一家公司的全球 DBA 的无穷智慧中,他创建了一个 table,它将 int 作为 ID 字段,但不会自动递增数字。
我正在传递一个来自 .Net 的 table 值参数,因为它有大约 100 行或更多行的数据在任何时候传递,我不想终止应用程序,锤击网络或 SQL 服务器。
所以这是我的存储过程
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 row(s) affected)
(1 row(s) affected)
(1 row(s) affected)
(1 row(s) affected)
(1 row(s) affected) Msg 2627, Level 14, State 1, Procedure sp_Insert_Supporting_Error_Info, Line 9 Violation of PRIMARY KEY constraint 'PK_CEQZW'. Cannot insert duplicate key in object 'dbo.CEQZW'. The duplicate key value is (1). The statement has been terminated.
所以我的问题是,除了破坏网络,应用程序和 SQL 服务器自动递增并将 ID 添加到 table
好吧,我首先要去找你的 DBA,问问他为什么决定不制作 ID 列和标识。也许他会改变主意。
但是,如果他会保留这个决定,请不要尝试自己创建自动递增机制。
99.9% 的情况它都有可能失败,尤其是在多用户环境中。
相反,使用标识列的已经内置的线程安全方法。
由于我们讨论的是不能直接在目标中使用身份列的情况 table,我建议使用 2012 版本中引入的序列对象的简单模拟来获得您的自动递增。
为此,您需要一个计数(数字)table。如果您的 DBA 尚未创建一个,请让他阅读 Jeff Moden 的 The "Numbers" or "Tally" Table: What it is and how it replaces a loop and then send him to KM.'s answer on this SO post 以获取创建脚本。 (方法 7 是我最喜欢的。)
现在你有一个数字 table,你添加一个非常简单的 table:
CREATE TABLE tblSequence
(
Value int identity(1,1)
)
然后,您创建一个存储过程,它将向这个 table 和 returns 新创建的值中插入任意数量的行(感谢 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.
我将其纳入您自己的程序由您决定。