dbo.Groups
というテーブルが次のように定義されています。
CREATE TABLE dbo.Groups
(
GroupID int NOT NULL IDENTITY (1,1) PRIMARY KEY
);
テーブルは実際には1つのIDENTITY
列だけで構成されています。
時には、一度に複数の行を挿入して、生成されたIDを取得したい場合があります。 (ID
句で使用するOUTPUT
列が1つある@output
という定義済みのテーブル変数がすでにあります。)
singleの行の場合、どのようにすればよいかがわかります。
INSERT INTO
dbo.GroupID
OUTPUT
inserted.GroupID INTO @output (ID)
DEFAULT VALUES
;
ただし、一度に2つ以上挿入できるようにしたい。実際の数は、このクエリによって返される行の数によって決まります。
SELECT
*
FROM
dbo.MySource
;
したがって、クエリが1行を返す場合、1行をdbo.Groups
に挿入して、生成されたGroupID
を返します。 100行の場合、100行が挿入され、100のIDが一度に生成および返されることを期待します。
1つの明白な方法は、ループで一度に1行を挿入することです。私はそれを避けて、代わりにセットベースのアプローチを使用したいと思います
INSERT INTO
dbo.GroupID
OUTPUT
inserted.GroupID INTO @output (ID)
SELECT
... -- what?
FROM
dbo.MySource
;
単一のステートメントで(できれば)IDENTITY
列だけを含むテーブルに複数の行を挿入する方法はありますか?
これを書いている時点では、IDENTITY
ステートメントを使用してINSERT
列に複数の行を挿入する方法はありません。 DEFAULT VALUES
プレースホルダーは、1行のみを表します。また、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
句は基本的にMERGE
を純粋なINSERT
に変換します。これは、明示的にfalseの条件により、すべてのソース行が一致せず、WHEN NOT MATCHED THEN
ブランチがトリガーされるためですステートメントの。これで、WHEN NOT MATCHED THEN
ブランチは単一行の挿入定義を期待します。ここでは、使い慣れたDEFAULT VALUES
が完全に有効です。その結果、任意の数の行に対してINSERT ... SELECT
の機能を備えたINSERT ... DEFAULT VALUES
ステートメントを効果的に取得できます。