
✅ はじめに
Access VBAでOO4O(Oracle Objects for OLE)からADO(ActiveX Data Objects)へ移行作業をしていると、
「SQL文はまったく同じなのに、なぜかフリーズする」という不思議な現象に出くわすことがあります。
しかも、原因はSQLでも接続でもなく、たった1行の“設定漏れ”。
この記事では、実際に起きたフリーズの原因と、その回避方法について解説します。
■ 現象:SQLは正しいのに、Recordset.Openで止まる
OO4O時代に問題なく動いていたこのようなSQL処理が…
※変数mySQLにSQL文が入っていてそれを実行するコード
Set OraDyn = g_OraDatabase.CreateDynaset(mySQL, ORADYN_READONLY)
ADOに書き換えて実行したところ、まったく進まない、応答なし、停止しないけど動かない…というフリーズ状態になりました。
Set rs = New ADODB.Recordset
rs.Open mySQL, g_con, adOpenStatic, adLockReadOnly
■ 原因:CursorLocation の指定漏れ
ADOでは Recordset を開く際に、カーソルの位置(CursorLocation)が非常に重要です。
デフォルトでは、adUseServer(サーバーサイドカーソル)が使用されますが、これが一部のプロバイダ(特にOracle)と相性が悪いことがあります。
この設定を省略したため、カーソルの取得処理で無限待機状態になっていたのです。
■ 解決方法:CursorLocation = adUseClient を明示的に指定
Set rs = New ADODB.Recordset
rs.CursorLocation = adUseClient ' ←これがないと止まる原因に!
rs.Open mySQL, g_con, adOpenStatic, adLockReadOnly
✔ なぜ adUseClient が必要なのか?
- クライアント側カーソルを使うことで、EOF/BOFなどの処理が安定
- サーバー側カーソルはプロバイダによっては正常に動かないことがある(Oracleなど)
- クライアントカーソルはメモリ上で扱うため、特に読み取り専用のSELECTには向いている
⚠ 注意:OO4Oから移行する際にハマりやすいポイント
項目 | OO4O(旧) | ADO(新) |
---|---|---|
カーソル設定 | 暗黙的に最適化 | 明示的に書かないと危険 |
接続の相性 | Oracle専用設計 | プロバイダ互換に注意が必要 |
エラーメッセージ | 比較的明示的 | 無言フリーズが起こることも |
■ まとめ:CursorLocationの1行が“命取り”になることも
ADO移行中に「SQLを変えていないのにフリーズする」場合、疑うべきはカーソルの設定漏れです。
■ チェックポイント:
- rs.CursorLocation = adUseClient を忘れていないか?
- SQL実行時にカーソルの種類(クライアント/サーバー)を確認したか?
- 特にOracleなど、ADOとの相性が微妙なプロバイダを使っていないか?
ほんの1行の違いで、動く/止まるが変わるのがADOの怖さでもあり、奥深さでもあります。
■ おまけ:安全なRecordsetテンプレート
Dim rs As ADODB.Recordset
Set rs = New ADODB.Recordset
rs.CursorLocation = adUseClient
rs.Open mySQL, g_con, adOpenStatic, adLockReadOnly
If Not rs.EOF Then
' ここで処理
End If
rs.Close Set
rs = Nothing
■ 関連記事
【Access VBA】OO4OからADOに移行後、SQLは同じなのにフリーズ?原因はカーソル設定
【Access VBA】「Object」と「ADODB.Connection」の違いとは?使い分けの解説
OO4O→ADOに移行する際のフォーム関数の呼び出し方の違いと注意点
【保存版】Oracle OO4O(Oracle Objects for OLE)とは?サポート終了とADOへの移行ガイド
■ 関連キーワード
- Access VBA ADO フリーズ
- Recordset.Open 止まる
- CursorLocation adUseClient 必要性
- ADO SQL 変更なし フリーズする
- ADO adUseServer adUseClient 違い
- OO4O ADO 移行 トラブル