2011-10-18 14 views
0

SQL Server 2008 Enterpriseで実行されているクエリに問題があります。 クエリは別のテーブルからのテーブルへの挿入ですが、レコードが1回だけ挿入されていることを確認します。SQLクエリはSQL Server 2008標準で実行されますが、企業では実行されません。

insert into A(...) 
--complex select from table B as b 
WHERE NOT EXISTS (SELECT 1 FROM A WHERE id = b.id) 

編集: クエリは、このような何かをして、このクエリは、次のん: Bから「複雑な選択が」記録45(= 45 idを持つすなわちレコード)を選択した場合は二回、その後場所です初めてレコード45が表示されるので、Aに挿入されます。 次に、レコード45が2回目に表示されます。where条件はfalseであるため、Aに2回挿入されません。

このクエリは、SQL Server 2008の標準版で正常に動作するため、問題はSQL Serverのバージョンの違い(既定の設定が異なるか何かのようなもの)です 最大挿入コミットサイズについては、それが問題なのかどうかはわかりません。 エラーメッセージはありません。唯一目に見えるエラーは、標準でレコード45を1回取得し、エンタープライズで2回取得することです。 すべてのアイデア?

+0

修正しようとしていること、またはしていないことは何ですか? –

+0

エラーメッセージが表示されますか? –

+0

あなたの質問に答えて質問を更新しました – dmorganb

答えて

0

クエリを再構築して正常に機能するかどうかを確認してください。代わりにNOT EXISTSのINSERTクエリでテーブルを結合:

INSERT A(...) 
SELECT ... FROM B LEFT JOIN A ON B.id = A.id 
WHERE B.id = 45 AND A.id IS NULL 

、あなたは一度だけ選択を行っています。

+0

問題は、クエリ全体が実行時に生成されるため、その変更を導入するのが難しいことです。さらに、クエリは機能しますが、SQL Server標準(これは使用可能な環境)でのみ動作します。ここの本当の問題は、企業では機能しない理由です... – dmorganb

1

あなたは、あなたがスタンダード版になっていると言う行動は、あなたが思っている以外の理由があると確信しています。

INSERTの値にINSERTEDとなる重複が含まれている場合、新たに追加された行が存在するため、NOT EXISTSはfalseと評価されるようです。しかしAFAIKはそれが動作するはずの方法ではありません。以下のように単純なINSERT .. SELECTを見てください。

CREATE TABLE A(id INT PRIMARY KEY) 

CREATE TABLE B(id INT PRIMARY KEY) 

INSERT INTO A 
SELECT * 
FROM B 

Sub queryを次のようにNOT EXISTS

INSERT INTO A 
SELECT * 
FROM B 
WHERE NOT EXISTS (SELECT 1 FROM A WHERE id = B.id) 

追加次計画

Simple Select

計画を変更与えます

アンチ・セミ・ジョインを含む計画だけでなく、クラスタ化インデックスを挿入する前にプランに熱心なスプールを追加したA。これはブロッキング演算子であり、Bにすべての行が挿入される前に、SELECT全体が評価されるようにします(Halloween Protectionに関連する)。

しかし、必ずしもプランにスプールが表示されているとは限りません。例えばSQL Serverでは、SORTやハッシュ・アンチ・セミ・ジョインなどの別のブロッキング演算子を使用することもできます。

少なくとも標準版、好ましくは両方の実行計画を掲載してください。あなたが未定義の構文を使用しているかどうかを調べるためのクエリもあります。