前提・実現したいこと
VBAで、ADOにてOracleDBからデータを取得するコードを書いています。
おおむねうまくいっていると思ったのですが、大量レコードが存在するテーブルに対してSelect文を発行すると、
重複レコードが含まれる形で結果が返ってきてしまいます。
発生している問題・エラーメッセージ
下記ソースコードを実行すると、
- 対象テーブルに存在するレコード数 + FetchSizeで指定した値 の結果が取得されてしまいます。
- 取得結果の内容を確認すると、FetchSizeで指定した値の分だけ、重複レコードが取得されてしまっていました。
(Execelにペーストしテーブルに変換した後、重複行を削除の操作で、FetchSizeで指定した値の分削除される)
- 重複レコードを削除した後は、本来のテーブルに存在するデータが取得されているように見えます。
(量が多いため検証しきれていませんが、重複レコードを削除した後であればDBに貼り付けてもエラーが起きない。重複行がある時点では、一意制約違反などでエラー)
下記に試したことを記載しておりますが、当方にはなぜこのような現象が発生するのか全く分かっていないため、
以下に心当たりがありましたら、ご助言いただけますと幸いです。
- 事象の原因
- 回避策(あれば。現在は、大きいテーブルを取得する場合は少しずつ取得する方法を検討しています)
該当のソースコード
VBA
1'SQLの実行 2Public Sub Test() 3 ' Create 4 Dim con As New ADODB.Connection 5 con.Provider = "OraOLEDB.Oracle" 6 con.ConnectionString = "FetchSize=8000;" & _ 7 "Data Source=(HOST):(PORT)/(DB);" & _ 8 "Persist Security Info=True;" & _ 9 "User ID=(USERID);Password=(PASS);" 10 con.Open 11 12 ' Select 13 Dim strSql As String 14 strSql = "select * from (大量レコードの存在するテーブル名)" ' レコード数は16000程度で発生 15 16 Dim recordSet As New ADODB.recordSet 17 recordSet.ActiveConnection = con 18 recordSet.CursorLocation = adUseServer 19 recordSet.LockType = adLockBatchOptimistic 20 recordSet.Open strSql, recordSet.ActiveConnection, adOpenStatic, adLockBatchOptimistic 21 22 Dim rCount As Integer 23 rCount = recordSet.RecordCount ' ここで取得できているレコード数がおかしい。 24End Sub
試したこと
- 重複レコード数が、ConnectionString の FetchSize に指定している値と同一であったため、
FetchSize の値をいろいろ変更してみました。
その結果、FetchSize が取得対象のテーブルのレコード数の半分以下だと、重複レコードが取得されてしまうことがわかりました。
- FetchSize に指定する値を大量レコードの数より大きくすれば、重複レコードが発生しません。
ただし、今回は取得対象が16000程度で発生したものの、30万程度レコードが存在するテーブルを対象とすることもあり、あまりFetchSize を大きくし過ぎるとメモリーが割り当てられず失敗してしまいます。
補足情報(FW/ツールのバージョンなど)
- Oracle:Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production
- MS Office 2016
回答3件
あなたの回答
tips
プレビュー