- 締切済み
CSVを取込むストアドプロシージャで、1件目が登録されない現象が起きています
いつもお世話になっております 古い環境なので大変恐縮ですが、行き詰ってしまったので、 ご教示いただきたいと思います。 環境: WinXP sp2 SQLServer8.0 VB6.0 sp4 VBでCSVのデータ1行について、ストアドプロシージャにて3つのテーブルに格納しようとしています。 トランザクションの管理はVB側で行っています。 1行ごとにCommitを行えば、全行格納されるのですが、 2行以上ごとにCommitを行うと、最初の1行のみが格納されないという現象がおきています。 6800行存在する同じCSVファイルについて、1行ごとにCommitを行った場合は、6800件登録されるのに 処理の最後でCommitをきった場合、6799行しか登録されません。 1行ごとにCommitをきった場合に6800行登録されるので、キー重複は考えられません。 いろいろ試してみたことを下記に書きます 結果はこのような感じです。 CASE1・・・全件登録できます CASE2・・・2件目で重複エラーが発生します CASE3・・・全件 - 1件が登録できます CASE4・・・全件登録できます CASE5・・・全件登録できます CASE2, CASE3 で全件登録できない理由をご教示いただきたく思います。 よろしくお願いいたします。 CASE1(VBでINSERT文を記述) localConnection.beginTrans localConnection.execute "DELETE FROM TABLE_A" localConnection.execute "DELETE FROM TABLE_B" localConnection.execute "DELETE FROM TABLE_C" FOR i = 1 to 6800 localConnection.execute "INSERT INTO TABLE_A (COL_A1, COL_A2) VALUES ('" & VAL_A1(i) & "','" & VAL_A2(i) & "')" localConnection.execute "INSERT INTO TABLE_B (COL_B1, COL_B2) VALUES ('" & VAL_A1(i) & "','" & VAL_B2(i) & "')" localConnection.execute "INSERT INTO TABLE_C (COL_C1, COL_C2) VALUES ('" & VAL_A1(i) & "','" & VAL_C2(i) & "')" NEXT localConnection.commitTrans CASE2(ストアドプロシージャ) localConnection.beginTrans localConnection.execute "DELETE FROM TABLE_A" localConnection.execute "DELETE FROM TABLE_B" localConnection.execute "DELETE FROM TABLE_C" ' -- ストアドプロシージャのパラメータ作成 FOR i = 1 to 6800 localConnection.execute NEXT localConnection.commitTrans CASE3(ストアドプロシージャ) localConnection.beginTrans localConnection.execute "DELETE FROM TABLE_A" localConnection.execute "DELETE FROM TABLE_B" localConnection.execute "DELETE FROM TABLE_C" localConnection.commitTrans ' -- ストアドプロシージャのパラメータ作成 localConnection.beginTrans FOR i = 1 to 6800 localConnection.execute NEXT localConnection.commitTrans CASE4(ストアドプロシージャ) localConnection.beginTrans localConnection.execute "DELETE FROM TABLE_A" localConnection.execute "DELETE FROM TABLE_B" localConnection.execute "DELETE FROM TABLE_C" localConnection.commitTrans ' -- ストアドプロシージャのパラメータ作成 localConnection.beginTrans FOR i = 1 to 6800 localConnection.execute localConnection.commitTrans localConnection.beginTrans NEXT localConnection.commitTrans CASE5(ストアドプロシージャ) localConnection.beginTrans localConnection.execute "DELETE FROM TABLE_A" localConnection.execute "DELETE FROM TABLE_B" localConnection.execute "DELETE FROM TABLE_C" localConnection.commitTrans ' -- ストアドプロシージャのパラメータ作成 localConnection.beginTrans FOR i = 1 to 6800 localConnection.execute if i = 1 then localConnection.commitTrans localConnection.beginTrans end if NEXT localConnection.commitTrans
- みんなの回答 (2)
- 専門家の回答
みんなの回答
- khazad-lefty
- ベストアンサー率44% (296/668)
- khazad-lefty
- ベストアンサー率44% (296/668)
補足
何度も大変ご丁寧な解説ありがとうございます。 昨日、この作業を含め、いろいろ試してみました。 やはり、重複が気になったので、FOR文のカウントをそのままキーに 入れてみたり、トランザクションの分離レベルを変更したりもしました。 ご教示いただいた内容について Executeの前後でレコードセットを調べてみました。 キー項目には、For文のカウントをCstrしてそのままキーに入れる(=重複はありえない)ようにしています。 1件目の直前ではゼロ件 / 直後で1件(1件目が正常に登録されている)、 2件目の直前では1件(1件目が正常に登録されている) になっており、2件目のExecuteで、VB側のエラーオブジェクトが重複エラーを検出しました。 VB側エラーオブジェクト err.Number -2147217873 err.Description PRIMARY KEY 違反、制約 'PK_TABLE_A': オブジェクト 'TABLE_A' には重複したキーは挿入できません。 もちろん、ストアドプロシージャ側でもエラーログを出力しており、 エラーがあった場合にはクライアントに返す処理も行っています ----------------------------------------------- INSERT INTO TABLE_A (...) VALUES (...) SELECT @Error = @@Error,@ROWCOUNT = @@ROWCOUNT if @Error != 0 BEGIN RaisError('<%s>(%s[%s]) TABLE_Aの挿入時にエラーが発生しました。 Error=%d',10,1,@PROCEDURE_NAME,@HostName,@ApName,@Error) WITH LOG,NOWAIT SET @o_ErrMsg = '<' + @PROCEDURE_NAME + '>TABLE_Aの挿入時にエラーが発生しました。 Error=' + @Error GOTO ErrHandle END ErrHandle: /* エラー発生 戻り値は1 */ RETURN 1 ----------------------------------------------- しかし、SQLServerのエラーログには記述されているものの、 そこからクライアントに1が返ってきているのではなく VB側のエラーオブジェクトでした。 また、この時点で気になったのが、RS をCloseするとVB側でエラーが検出され、 RSをCloseしないと、2件目以降が正常に登録されていくということを確認しています。 トランザクションの分離レベルも、READ UNCOMMITTEDにしてみましたが、 やはり、重複エラーを返すようです。 まだ決定的ではありませんが、今のところ、下記の推測がたちました。 ・beginTrans → VB側でDELETE → ストアドでINSERT → commitTrans の流れで、 DELETEが確実に行われていないのではないだろうか? これから、他のテーブルでも同じような現象が起きるかどうかを調べてみます。 ありがとうございました。