I’m working on a trigger which needs to re-insert its data on another table.
The destination table has a primary key INT NOT NULL WITHOUT Identity, so I have 2 choices:
- Calculate the maximum and insert from here.
- Take max value from a sequences table.
I use to always create a table variable with identity and insert shifting from the value calculated before.
CREATE TRIGGER trg
ON [dbo].[table]
AFTER INSERT
AS
BEGIN
SET NOCOUNT ON;
DECLARE @t TABLE (sec INT IDENTITY(1, 1), id INT)
DECLARE @ini INT
SELECT @ini = ISNULL(MAX(id), 0) FROM tableDest
-- SELECT @ini = value FROM sequencesTable WHERE seqId = 987
INSERT INTO @t (id) SELECT id FROM inserted
INSERT INTO tableDest
(id, field1, field2)
SELECT @ini + t.sec, field1, field2
FROM @t t
JOIN inserted ON t.id = inserted.id
-- SELECT @ini = @ini + MAX(t.sec) FROM @t
-- UPDATE sequencesTable SET value = @ini WHERE seqId = 987
END
Is it any better way to do this?
Thanks in Advance.
Assuming SQL 2005+, you can use ROW_NUMBER():
Doing a
CROSS JOINinstead of getting the seed value directly saves you from the concurrency headache ofMAX(Id)changing between getting the value and inserting it. Otherwise, you’d need aSERIALIZABLEtransaction to prevent new rows from being inserted into tableDest after you read it.