- ベストアンサー
SQL文が化ける原因と対策を教えてください
- VB6.0でADOを使用してSQLServer2005に接続しています。あるSELECT文を取得条件だけ変更して連続して発行し、結果を変数に取り込むプログラムで、なぜか4000~5000件ごとにSQLがタイムアウトしてしまいます。
- プロファイラで確認したところ、VB側で発行したSELECT文の頭になぜか「select * from」がくっついたSQL文が表示されます。前後のSQL文は正しく動いており、SQL文が間違っているように思えません。
- このような現象は、連続して発行するSQLの件数が少ないときは発生しませんでした。原因がわからず、修正もできず困っています。アドバイスよろしくお願いいたします。
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
これはODBCですね。 再現すれば苦労はないのですが、同じ構造で何万回コールしても再現させられませんでした(XP SP3 & SQL Server 2005)。 再現させられない以上、私としては代替案をお勧めするしかないのですが、 ・プロバイダを変更してみる a) psAConnect = "Provider=SQLOLEDB;Data Source=(サーバー);Initial Catalog=(データベース);User ID=(ユーザ);Password=(パスワード);" b) psAConnect = "Provider=SQLNCLI;Data Source=(サーバー);Initial Catalog=(データベース);User ID=(ユーザ);Password=(パスワード);" ・1万回以上もSQL文を投げる構造を改める この書き方をしている以上はキー項目はローカルにあるのでしょうが、そこまでヒット率が低いなら全部取ってきてローカルで調べた方がいいと思います。 (もしくはIN句で100~1000件単位でまとめて検索するか) 今の方法だとすべてのSQL文が別物とみなされてキャッシュが殆ど使われないので、さらに遅いと思いますしね。
その他の回答 (2)
- jamshid6
- ベストアンサー率88% (591/669)
#1です。 >お礼の文章がなんだか失礼に見えてしまったので 全然気にする必要はありません。失礼な表現でもないと思います。 回答する側としては、役に立ったか/立たなかったかさえ分かればそれで構わないですし、 仮に役に立たなくても自分のスキル維持には役立ちます(ADOは今仕事で書いていないですしね)。
お礼
SQLを何が何でも投げる構造を見直し、必要な場合のみSQLをなげる条件をVB側で追加することで、問題の回避ができそうです。 jamshid6さんから回答をいただくことで、問題点の整理ができました。 ありがとうございました。
- jamshid6
- ベストアンサー率88% (591/669)
・ADOの構文も何パターンもありますが、どうやってSQLを投げているのか ・MDACのバージョンは ・使っているプロバイダは といった情報がないと再現するかどうかも確認できないですね。 SQL ServerはSQL文を受け取っている方であって、「select * from」はVB側(厳密にはADO)がつけているわけですから。 (投げたSQL文がテーブルと誤認されれば、select * fromがついてしまう可能性があるかなと思いますが。。)
補足
ありがとうございます。補足いたします。 MDACのバージョンは2.8 SP1(WindowsXP SP3)です VB6の参照設定で、Microsoft ActiveX Data Objects 2.8 Library (msado15.dll)を参照する設定にしています。 接続時プロバイダは指定しておりませんので、ADOのデフォルトの Microsoft ODBC Provider for OLE DB と思います。 リトライ処理、エラー処理等をカットして、コードをまとめてみました。 --------- Public psAConnect As String 'ADODB接続文字列 Public pADB As ADODB.Connection 'ADOコネクション --------- If pADB Is Nothing Then Set pADB = CreateObject("ADODB.Connection") End If pADB.ConnectionTimeout = 60 pADB.CommandTimeout = 180 psAConnect = "Driver=SQL Server;Server=(サーバー);Database=(データベース);UID=(ユーザ);PWD=(パスワード);" pADB.Open psAConnect --------- Dim rsRec As ADODB.Recordset Dim sSQL As String sSQL = (質問文のSQL。WHERE ID番号 ='00AZ6535' の部分がかわります。) Set rsRec = pADB.Execute(sSQL, , adCmdText) --------- このあと、取得したレコードセットを変数に代入処理し、 rsRec.Closeし、次のID番号でのレコードセット取得にうつります。 実際のID番号件数は約17000件です。 また、実際は「区分」テーブルに10件程度しかデータがないため、このSQLで取得するレコードセットは0件の場合がほとんどです。 よろしくお願いいたします。
お礼
ありがとうございます。 私が試験をしたときも、サーバーを変えると再現しない場合がありました。 SQLServer2005試用版で、セットアップ時に「スペックが足りない」と警告されるようなサーバーを使用して試験したときでした。 お勧めいただいた「1万回以上もSQL文を投げる構造を改める」方法を検討してみます。 ありがとうございました。
補足
すいません、お礼の文章がなんだか失礼に見えてしまったので、お礼の補足です。 決してjamshid6さんに試験していただいた環境が悪い、と申しているわけではありませんので、どうかそのようにお読みください。 再現試験していただき、アドバイスをいただいたこと、本当に感謝しています。 ありがとうございました。