我使用主键(TicketID
)作为identity
列,每次生成票证时都会自动递增。一切顺利,然后我开始看到我的TicketID
从5,6跳到1007,1008。
通过Google搜索,我在SQL Server 2012中找到了这个设计:
http://connect.microsoft.com/SQLServer/feedback/details/743300/identity-column-jumps-by-seed-value
现在我想自定义创建一个列,它会像标识列一样自动递增,但不会跳转并留下空白(我不想要identity
列)
我该怎么做?我认为触发器是我正在寻找的,但由于我之前从未使用过触发器,我真的很感激这里的一些帮助。
或者我应该使用计算列吗?
答案 0 :(得分:2)
创建自己的自动增量机制是一个坏主意。
查看SEQUENCE对象http://technet.microsoft.com/en-us/library/ff878091.aspx
但如果您仍想这样做,一种可能的解决方案
CREATE TABLE dbo.TicketNumber
(
Number INT NOT NULL
)
INSERT INTO dbo.TicketNumber(Number) VALUES(0)
CREATE PROCEDURE dbo.sp_GenerateTicketNumber
(
@Number INT OUT
)
AS
BEGIN
DECLARE @Number INT
DECLARE @CurrentNumber INT
BEGIN TRANSACTION
SELECT
@CurrentNumber = Number
FROM dbo.TicketNumber WITH(UPDLOCK)
SET @Number = @CurrentNumber + 1
UPDATE dbo.TicketNumber
SET Number = @Number
COMMIT TRANSACTION
END
dbo.sp_GenerateTicketNumber 的替代实现可能看起来像
DECLARE @number TABLE(number INT);
UPDATE dbo.TicketNumber
SET
[Number] = [Number] + 1
OUTPUT INSERTED.Number INTO @number;
SELECT * FROM @number
您想要的解决方案,可能是
CREATE PROCEDURE dbo.sp_RegisterTicket
(
@PersonName varchar(255),
@TicketNumber INT OUT
)
AS
BEGIN
BEGIN TRAN
SELECT
@TicketNumber = MAX(TicketId) + 1
FROM dbo.Tickets WITH(UPDLOCK)
INSERT INTO dbo.Tickets VALUES(@TicketNumber, @PersonName)
COMMIT TRAN
END
使用示例:
DECLARE @Number INT
EXEC dbo.sp_RegisterTicket 'Vasya', @Number OUT
SELECT @Number
答案 1 :(得分:1)
我刚刚使用AFTER INSERT触发器解决了我的问题。 这就是我所做的。
ALTER TRIGGER [dbo].[tid2]
ON [dbo].[tblPrac2]
AFTER INSERT
AS
declare @nid int;
set @nid = ( select MAX(TicketID) from [tblPrac2] );
if(@nid is null)
begin
set @nid = 1;
end
else
set @nid = @nid + 1;
update tblPrac2 set TicketID = @nid where ID in (select ID from inserted)
答案 2 :(得分:0)
答案 3 :(得分:0)
您无法操纵IDENTITY列以保持无间隙。 为了实现您的需求,您必须使用具有单列和行的表来存储TicketID的当前最大值以及用于访问此值的存储过程,如果插入发生则将其增加1,如果发生删除则减1 。 当然,这会影响性能,而不是使用IDENTITY列并忽略差距。