1

我有一个表,我需要将记录从回复制到自身。作为其中的一部分,我想使用 OUTPUT 子句将新行捕获到表变量中,这样我就可以在同一进程中对行执行其他操作。我希望每一行都包含它的新键和它从中复制的键。这是一个人为的例子:

INSERT 
    MyTable (myText1, myText2) -- myId is an IDENTITY column
OUTPUT  
    Inserted.myId, 
    Inserted.myText1, 
    Inserted.myText2 
INTO
    -- How do I get previousId into this table variable AND the newly inserted ID? 
    @MyTable    
SELECT 
    -- MyTable.myId AS previousId,
    MyTable.myText1,
    MyTable.myText2
FROM
    MyTable
WHERE
    ...

如果 INSERT 上的列数与 SELECT 语句中的列数不匹配,SQL Server 就会发出声音。因此,如果我向 MyTable 添加一列,我可以看到这会如何工作,但这不是一个选项。以前,这是使用导致性能瓶颈的游标实现的——我故意试图避免这种情况。

如何复制这些记录,同时保留复制行的键以实现最高性能?

4

1 回答 1

1

I'm a little unclear as to the context - is this in an AFTER INSERT trigger.

Anyway, I can't see any way to do this in a single call. The OUTPUT clause will only allow you to return rows that you have inserted. What I would recommend is as follows:

DECLARE @MyTable (
    myID INT, 
    previousID INT, 
    myText1 VARCHAR(20), 
    myText2 VARCHAR(20)
)

INSERT @MyTable (previousID, myText1, myText2) 
SELECT myID, myText1, myText2 FROM inserted

INSERT MyTable (myText1, myText2) 
SELECT myText1, myText2 FROM inserted

-- @@IDENTITY now points to the last identity value inserted, so...
UPDATE m SET myID = i.newID
FROM @myTable m, (SELECT @@IDENTITY - ROW_NUMBER() OVER(ORDER BY myID DESC) + 1 AS newID, myID FROM inserted) i
WHERE m.previousID = i.myID

...

Of course, you wouldn't put this into an AFTER INSERT trigger, because it will give you a recursive call, but you could do it in an INSTEAD OF INSERT trigger. I may be wrong on the recursive issue; I've always avoid the recursive call, so I've never actually found out. Using @@IDENTITY and ROW_NUMBER(), however, is a trick I've used several times in the past to do something similar.

于 2012-03-05T17:19:33.400 回答