Reputation: 864
I was using the primary key (TicketID
) as an identity
column which was auto incrementing on every time a ticket is generated. Everything was going smoothly and then I started seeing that my TicketID
jumps from 5,6 to like 1007, 1008.
Upon googling, I found about this design-by in SQL Server 2012:
http://connect.microsoft.com/SQLServer/feedback/details/743300/identity-column-jumps-by-seed-value
Now I want to custom create a column, which will auto increment just like identity column but does not jump and leave gaps (I don't want an identity
column)
How should I do that? I think triggers are what I am looking for but as I have never used triggers before, I would really appreciate some help here.
OR should I use computed column?
Upvotes: 1
Views: 2581
Reputation: 864
I have just solved my problem using a AFTER INSERT trigger. Here it is what I did.
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)
Upvotes: 1
Reputation: 1465
Create you own autoincrement mechanism is a bad idea.
Look at SEQUENCE object http://technet.microsoft.com/en-us/library/ff878091.aspx
But if you still want to do this, one possible solution is
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
The alternative implementation of dbo.sp_GenerateTicketNumber may be looks like
DECLARE @number TABLE(number INT);
UPDATE dbo.TicketNumber
SET
[Number] = [Number] + 1
OUTPUT INSERTED.Number INTO @number;
SELECT * FROM @number
And the solution you want, probably
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
Using example:
DECLARE @Number INT
EXEC dbo.sp_RegisterTicket 'Vasya', @Number OUT
SELECT @Number
Upvotes: 2
Reputation: 28771
You cannot manipulate IDENTITY column to remain without gaps . For implementing your requirement , you will have to use a table with single column and row which stores the current maximum value of TicketID and a stored procedure to access this value , increase it by 1 if insertion takes place and subtract by one if deletion takes place. Of course this will have impact on performance vs using IDENTITY column and ignoring the gaps.
Upvotes: 0
Reputation: 39477
You can use unique identifier, I think.
http://technet.microsoft.com/en-us/library/ms187942.aspx
But it takes more space of course.
Upvotes: 0