2016-07-05 8 views
0

次のクエリがあります。 - テーブルltr_programを循環してその値を新しく作成したテーブルに挿入するカーソル。新しく作成されたテーブルにidフィールドも追加されます。SQL Server:cursor存在しない場合に行を挿入します。

私は、ターゲットテーブルにまだ存在していない場合にのみ、そのIDを追加するのに苦労しています(ジョブは定期的に実行され、時間がたつにつれて新しいIDが追加されます)。新しく作成したデータを追加するだけで、コードをよりダイナミックにしたいと思っています。

DECLARE @next int, @program int 

DECLARE insert_cursor CURSOR FOR 
    SELECT id 
    FROM ltr_program 

OPEN insert_cursor 

FETCH NEXT FROM insert_cursor INTO @program 

WHILE @@FETCH_STATUS = 0 
BEGIN 
    SET @next = (SELECT MAX(id) FROM LTR_Budget) + 1      

    INSERT INTO LTR_Budget (id, ProgramID) 
     SELECT @next, @program 

    FETCH NEXT FROM insert_cursor INTO @program 
END 

CLOSE insert_cursor 
DEALLOCATE insert_cursor 

これはトリックを行う必要があります

+0

MySQLまたはSQL Server?私は恐れることができません。 –

+0

申し訳ありませんが、SQL Server(速いをクリックするとどうなりますか) – Elizabeth

+0

カーソルを使用しないでください。これは単一の挿入ステートメントでなければなりません。もちろん、アイデンティティを使用する代わりに、独自のロールを使用して値を増やすと、並行性の問題が発生する可能性があります。 –

答えて

0

、ありがとうございます。

INSERT INTO LTR_Budget (id, ProgramID) 
SELECT @next, @program 
where @program NOT IN (select distinct ProgramID from LTR_Budget) 

FETCH NEXT FROM insert_cursor INTO @program 

ただし、実際にはカーソルなしでこれを書き直すことを検討する必要があります。 あなたは(LTR_Budetに)自動的に各挿入をインクリメントIDENTITY列をIDを作成し、これを書き換えることができます:非常にクリーンになり

INSERT INTO LTR_Budget (id, ProgramID) 
SELECT id as ProgramID 
FROM ltr_program where id NOT IN (SELECT DISTINCT ProgramID from LTR_Budget) 

+0

IDフィールドをIDに更新しました。これは働いてくれてありがとう! – Elizabeth

+0

間違いなく。答えでは言及しませんでしたが、おそらくID列にインデックスを投げたいと思うでしょう。多くの人がPRIMARY KEYをそこに置いています(一意であり、NULLでないことが保証されているので) –

1
DECLARE @next INT; 
SET @next = (SELECT MAX(id) FROM LTR_Budget); 

INSERT INTO LTR_Budget (id, ProgramID) 
SELECT 
    ROW_NUMBER() OVER (ORDER BY p.id) + @next, 
    p.id 
FROM 
    ltr_program p 
LEFT JOIN 
    LTR_Budget b 
     ON p.id = b.id 
WHERE 
    b.id IS NULL; 
関連する問題