【问题标题】:Copy table rows using OUTPUT INTO in SQL Server 2005在 SQL Server 2005 中使用 OUTPUT INTO 复制表行
【发布时间】:2012-03-05 16:13:24
【问题描述】:

我有一个表,我需要将记录从该表复制回自身。作为其中的一部分,我想使用 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 添加一列,我可以看到这会如何工作,但这不是一个选项。以前,这是使用导致性能瓶颈的游标实现的——我故意试图避免这种情况。

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

【问题讨论】:

  • 正如您所提到的,最简单的方法是使用一个额外的列来容纳旧 ID。添加列不是选项的原因是什么?
  • 是的,我认为您是对的,但该列在此复制操作之外没有意义——如果没有其他结果,我想我并不完全反对。跨度>
  • 这并不像你说的那样理想,因为它并不是真正的数据的一部分。我想您可以将列添加为过程的一部分,然后将其删除,但这似乎有点笨拙。我很想使它可以为空,并确保在使用后将列清空以节省空间(假设您不需要在过程之外保留旧的 ID 值)
  • 如果您使用的是 SQL Server 2008,则可以使用 mergestackoverflow.com/questions/5365629/…
  • @Mikael Eriksson 是的,我希望能够使用 MERGE。

标签: sql-server performance sql-server-2005 insert output-clause


【解决方案1】:

我有点不清楚上下文 - 这是在 AFTER INSERT 触发器中吗?

无论如何,我看不出有任何方法可以在一次通话中做到这一点。 OUTPUT 子句只允许您返回已插入的行。我的建议如下:

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

...

当然,您不会将其放入 AFTER INSERT 触发器中,因为它会给您一个递归调用,但您可以在 INSTEAD OF INSERT 触发器中执行此操作。我可能在递归问题上错了;我一直避免递归调用,所以我从来没有真正发现。然而,使用 @@IDENTITY 和 ROW_NUMBER() 是我过去多次使用的技巧来做类似的事情。

【讨论】:

  • 我不认为这是一个触发器。我相信这只是一个普通的 SP。
猜你喜欢
  • 1970-01-01
  • 2010-09-05
  • 2010-10-21
  • 1970-01-01
  • 2012-05-07
  • 2013-01-08
  • 1970-01-01
  • 2011-01-10
相关资源
最近更新 更多