2017-01-18 11 views
1

ID列を持つSQL Serverにテーブルがあります。ID列に手動で1つのクエリで値を自動的に挿入します。

N + M行を挿入する必要があります。 N行の場合、ID列の値を手動で挿入する必要があります。他のM行については、identity列の値を自動生成する必要があります。

入力データの各行には、値を自動生成するか手動で作成するかを定義する属性(ビット列)があります。 N行のSET IDENTITY_INSERT ON有するもの、およびM行のIDENTITY_INSERT OFFと別の -

Iは二つの別個のINSERTステートメントでそれを達成することができます。

質問:は、1つのINSERTステートメントで実現できます。 ID列の値を生成する組み込み関数を使用していますか?

+0

? SQL Server 2012には「SEQUENCE」があります。 –

+0

SQL 2016 SP1を使用しています – Anton

答えて

2

いくつかのシミュレーションアイデンティティ挿入:SQL Serverのどのバージョンを使用してください

CREATE TABLE #Test (Id int IDENTITY(1,1) PRIMARY KEY, Value int) 

INSERT INTO #Test 
VALUES 
(100), 
(200) 

SELECT * 
FROM #Test AS t 

DECLARE @Temp TABLE (Id int, Value int, SetId bit) 
INSERT INTO @Temp 
VALUES 
(-1, 1,1), 
(-2, 2,1), 
(-1, 33,0), 
(-1, 44,0) 

SET IDENTITY_INSERT #Test ON 

INSERT INTO #Test 
(Id, Value) 
SELECT 
    CASE(t.SetId) 
     WHEN 1 THEN t.Id --just insert new Id 
     WHEN 0 THEN 
      IDENT_CURRENT('#Test') --get last identity value 
      + ROW_NUMBER() OVER(ORDER BY t.Id) --simulate identity +1 
      - (SELECT COUNT(*) FROM @Temp AS t2 WHERE t2.SetId = 1) --skip inserted rows with Id 
      + 1 
    END, 
    t.[Value] 
FROM @Temp AS t 

SET IDENTITY_INSERT #Test OFF 

SELECT * 
FROM #Test AS t 

DROP TABLE #Test 
+0

ありがとう、Backs!このメソッドは、2つの別々のINSERTよりも優れたパフォーマンスを発揮すると思いますか?時には、ターゲット表とソース表には数百万行が含まれている場合があります。 IDENT_CURRENT()は、ID列が自動生成されているときに、挿入されたすべての行に対してSQLエンジンが呼び出すのと同じ機能ですか? – Anton

+0

@Anton私は、2つの別々のインサートがはるかに優れていると思います。あなたは維持しやすい簡単なコードを得るでしょう。 'IDENT_CURRENT'はテーブルの最後に生成されたIDを返します:https://msdn.microsoft.com/en-us/library/ms175098.aspx – Backs

+1

' IDENT_CURRENT'を使用すると、 2つの別々のプロセスが同時に値を挿入しようとする可能性があります。 2つの独立したINSERTは常に正しく動作します。 –

関連する問題