Sql-Server

將多行插入到只有 IDENTITY 列的表中

  • December 4, 2019

我有一個dbo.Groups這樣定義的表:

CREATE TABLE dbo.Groups
(
 GroupID int NOT NULL IDENTITY (1,1) PRIMARY KEY
);

該表實際上只包含一IDENTITY列。

有時我想一次插入多行並獲取生成的 ID。(我已經有一個預定義的表變數,在子句中使用@output單個ID列呼叫。)OUTPUT

現在我知道如果它是單行我將如何進行:

INSERT INTO
 dbo.GroupID
OUTPUT
 inserted.GroupID INTO @output (ID)
DEFAULT VALUES
;

但我希望能夠一次插入兩個或更多。實際數量取決於此查詢返回的行數:

SELECT
 *
FROM
 dbo.MySource
;

因此,如果查詢返回一行,我想插入一行dbo.Groups並返回生成的GroupID. 如果它是一百行,那麼我預計會插入一百行,並立即生成和返回一百個 ID。

一種明顯的方法是在循環中一次插入一行。我想避免這種情況,而是使用基於集合的方法,類似於

INSERT INTO
 dbo.GroupID
OUTPUT
 inserted.GroupID INTO @output (ID)
SELECT
 ...  -- what?
FROM
 dbo.MySource
;

有沒有辦法將多行插入到一個表中,而表中只有一個IDENTITY列(最好是)一個語句?

在撰寫本文時,無法IDENTITY使用INSERT語句將多行插入到一列中。DEFAULT VALUES佔位符僅代表一行。並且語法沒有擴展來支持與子句INSERT ... SELECT相同的功能。DEFAULT VALUES

相反,您可以使用MERGE語句來實現目標:

MERGE INTO
 dbo.Groups AS tgt
USING
 dbo.MySource AS src  -- << use your source row set here
ON
 1 = 0
WHEN NOT MATCHED THEN
 INSERT DEFAULT VALUES
OUTPUT
 INTO @output (ID)
;

ON 1 = 0子句基本上將 theMERGE變成了 pure INSERT,因為顯式 false 條件導致所有源行不匹配,從而觸發WHEN NOT MATCHED THEN語句的分支。現在,WHEN NOT MATCHED THEN分支需要一個單行插入定義,熟悉的地方DEFAULT VALUES是完全有效的。結果,您有效地獲得了具有任意行數INSERT ... SELECT功能的語句。INSERT ... DEFAULT VALUES

引用自:https://dba.stackexchange.com/questions/254771