
DB:SQLServer2000
こんにちは
お世話になっております。
トランザクションのテーブルA から ワークのテーブルBへInsert Into Select を使用してデータを格納しているのですが、その際に重複が発生してしまいます。
テーブルA 主キーあり
テーブルB 主キーなし
Delete B
Insert into B select 項目1,項目2,・・・
from A With(Nolock)
where 日付項目 = 20080101
テーブルAの主キー項目は全てテーブルBへInsertしており、Insert完了後のテーブルBの中身を見ると、まれに全く同じデータが2件出来ていることがあります。
このInsert into selectが実行されている間に、テーブルAに対して登録更新が行われることもあります。
色々と試してはいるのですが、原因が特定できずに困っております。
もし何かお気づきになられる方がいらっしゃいましたら、ご教示下さい。
よろしくお願い致します。
No.5ベストアンサー
- 回答日時:
>>・すでに存在するレコードA1をテーブルAにInsertして(これがCOMMITするまではエラーにならないとして)、COMMITしないうちにSELECTされる
>⇒十分にあり得るとは思いますが、この様な場合は、既に存在するレコードA1と新たにInsertされようとした重複するレコードA1’がNolockでSelectした場合2件抽出されることになるのでしょうか?
理論上はあり得ると思いますね。
ただROLLBACKのログがない、ということですから、これもあり得ないということでしょうか。
エラーになったらROLLBACKされるはずですよね。
となると、いよいよわかりません。
ご回答ありがとう御座います。
>ただROLLBACKのログがない、ということですから、これもあり得ないということでしょうか。
>エラーになったらROLLBACKされるはずですよね。
そうですね。これもあり得ないことになってしまいます。
色々ありがとうございました。
まだ、あきらめずに調べて行きたいと思います。
No.4
- 回答日時:
ということは、
「Insert into B select 項目1,項目2,・・・
from A With(Nolock)
where 日付項目 = 20080101」
の対象になるようなレコードが、これを実行中にテーブルAにInsertされる可能性がある、ということですね?
・すでに存在するレコードA1をテーブルAにInsertして(これがCOMMITするまではエラーにならないとして)、COMMITしないうちにSELECTされる、とか
・2つのトランザクションからともにレコードA1をテーブルAにInsertしようとして、この2つがCOMMITしないうちにSELECTされる、とか
・1つのトランザクションが
レコードA1をテーブルAにInsert
→SELECTされる
→InsertをROLLBACK
→レコードA1をテーブルAにInsert
→InsertをCOMMIT
→再びSELECT
とか・・・
はありえないですかね?
ご回答ありがとう御座います。
またまた、お礼が遅くなり申し訳御座いません。
>これを実行中にテーブルAにInsertされる可能性がある、ということですね?
⇒その通りです。Insert・Updateがあり得ます。
>・すでに存在するレコードA1をテーブルAにInsertして(これがCOMMITするまではエラーにならないとして)、COMMITしないうちにSELECTされる
⇒十分にあり得るとは思いますが、この様な場合は、既に存在するレコードA1と新たにInsertされようとした重複するレコードA1’がNolockでSelectした場合2件抽出されることになるのでしょうか?
>・2つのトランザクションからともにレコードA1をテーブルAにInsertしようとして、この2つがCOMMITしないうちにSELECTされる
⇒テーブルAにInsertを行うトランザクションは1つしかない為、この様なことは無いと思います。
>1つのトランザクションが
>レコードA1をテーブルAにInsert
>→SELECTされる
>→InsertをROLLBACK
>→レコードA1をテーブルAにInsert
>→InsertをCOMMIT
>→再びSELECT
⇒これは、Insert into Selectが流れている間に、一連の流れが行われるということでしょうか。それとも2度Insert into Selectが実行されるということでしょうか。
前者の場合、あり得るとは思いますが、事実上テーブルAの登録する際にROLLBACKはかかっておりません。
(ROLLBACKの際にはエラー情報としてログが出力されるが、そのログが存在していない為)
後者の場合、テーブルAのSELECTを行う前にテーブルBはクリアされる為、重複はしないと思われます。
色々お手間掛けまして申し訳御座いません。
よろしくお願い致します。
No.3
- 回答日時:
すみませんが、わかりません。
Nolockが少し気になります。
他のロックに変えたら発生しないということはないですかね。
ご回答ありがとう御座います。
>Nolockが少し気になります。
>他のロックに変えたら発生しないということはないですかね。
私もNolockが一番怪しいのではと考えておりますが、どうしてもSQLの修正を行う前に原因を特定する必要がありましたので、Nolockを外したり等のテストを実際のSQLで行うことが出来ず、また、テスト環境で同様のSQLを実施したりしておりますが、現象(重複)の再現すら出来ずに行き詰っていた次第です。
すいません。本当は色々変更して試せれば良いのですが諸事情により本番のSQLを変更しての確認が出来ず、またテスト環境での再現が出来ていないことが最大のネックになっております。
私が今考えているのは、Nolockを使用することにより、テーブルAに更新が行われた際に、テーブルBへのINSERTが同時に処理され、未コミットデータがまずSELECTにて抽出され、INSERT。その同じタイミングで更新がコミットされ、そのコミットされたデータが再び、SELECTにて抽出され、INSERTされているのではと考えていますが、この様なことは実際にありえるのか、調査しているところです。
もし、何かご存知でしたら、ご教示頂けると幸いです。
No.2
- 回答日時:
「このInsert into selectが実行されている間に、テーブルAに対して登録更新が行われることもあります」
とのことですが、これはどのような登録・更新でしょうか?
「select 項目1,項目2,・・・
from A With(Nolock)
where 日付項目 = 20080101」
の内容が変わることもあるような更新でしょうか?
ご回答ありがとう御座います。
お礼が遅くなってしまい申し訳御座いません。
>これはどのような登録・更新でしょうか?
登録は単純に新規データの登録が行われます。
更新はテーブルAに持っているフラグ項目の更新です。0→1など
>内容が変わることもあるような更新でしょうか?
この内容が変わることはありません。
よろしくお願い致します。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
IFで条件を分岐させてのINSERT...
-
ACCESS 一番最新の日付の金額...
-
ビューで引数を使いたい
-
BETWEEN A AND B
-
2つのテーブルを結合して合計(...
-
空のテーブルの判別
-
複数のテーブルから同じ条件で...
-
「マスタ」と「テーブル」の違...
-
3つ以上のテーブルをUNIONする...
-
Accessにインポートしたら並び...
-
ACCESS2007 フォーム 「バリア...
-
オラクルではできるのにSQLSERV...
-
DataTableから条件を満たした行...
-
SELECT時の行ロックの必要性に...
-
主キーにインデックスは貼らな...
-
accessのロック
-
実行時エラー3086 削除クエリ...
-
Access VBA [リモートサーバー...
-
排他ロックしたレコードが、別...
-
ACCESSのODBCリンクテーブルに...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
ビューで引数を使いたい
-
ACCESS 一番最新の日付の金額...
-
IFで条件を分岐させてのINSERT...
-
複数のテーブルから同じ条件で...
-
Insert Into Select での重複に...
-
SQL文で
-
MS Accessの抽出の仕方について...
-
データベース設計のこと
-
Accessで在庫管理を
-
大学でSQLの授業があるのですが...
-
Sql文のUpdateと副問い合わせで...
-
select into句のトランザクショ...
-
SQLでの更新クエリに関する質問
-
(初心者です)パフォーマンス...
-
BETWEEN A AND B
-
空のテーブルの判別
-
年齢分布テーブルの再集計SQL
-
SELECT時のパフォーマンス
-
リレーションシップ 全データを...
-
where条件内のin句について
おすすめ情報