Here is what I was trying to get at with my line of questioning. If your central IDENTITY
generator has an additional, useless column, this can avoid inserting rows with DEFAULT VALUES
, which is difficult, cumbersome and downright unintuitive to do with more than one row (and perhaps impossible on, say, SQL Server 2005). So, pretending this generator table looks like this:
CREATE TABLE dbo.OtherTable(OtherTableID INT IDENTITY(1,1), UselessColumn BIT);
And the real table you're inserting into looks like this:
CREATE TABLE dbo.MyTable(ID INT IDENTITY(1,1), [No] INT, foo VARCHAR(32));
We can create an INSTEAD OF INSERT
trigger that inserts multiple rows into dbo.OtherTable
, captures the set of IDENTITY
values generated, then ultimately inserts those values along with the real data, assigning each generated value to a single row, arbitrarily.
CREATE TRIGGER dbo.trMyTable
ON dbo.MyTable
INSTEAD OF INSERT
AS
BEGIN
SET NOCOUNT ON;
DECLARE @newIDs TABLE(ID INT IDENTITY(1,1), [No] INT);
INSERT dbo.OtherTable(UselessColumn)
OUTPUT inserted.OtherTableID INTO @newIDs([No])
SELECT NULL FROM inserted;
INSERT dbo.MyTable([No],foo)
SELECT n.[No], i.foo FROM @newIDs AS n
INNER JOIN
(
SELECT *, rn = ROW_NUMBER() OVER (ORDER BY foo) FROM inserted
) AS i ON i.rn = n.ID;
END
GO
The reason an INSTEAD OF INSERT
trigger is better is because it avoids a double operation (insert a bunch of rows, then update them all). Obviously you have more columns than foo
; this is just as a simplistic demonstration.
If you also have to do something like this for batch updates, you're going to have to update the question with more requirements (and include information like what is the primary key on the target table).