【VBA】実行時エラー 3146 [ODBC–呼び出しが失敗しました。]

Access VBA

はじめに

VBAでODBCを使用していた場合、このようなエラーが出現することがよくあります。
しかし何が原因で失敗しているのかよくわからないため、原因究明に時間がかかることがあります。

本記事は原因究明を簡単にするコードを紹介します。

本当のエラー文を取る(最小コード)

“中身のエラーを隠した汎用メッセージ”なので、
まず本当の ODBC/Oracle 側のエラー文を出しましょう。出れば対処法が決められます。

On Error GoTo EH

' ★ここにエラーが出る処理(DoCmd.OpenQuery / qdef.Execute / レポート表示 など)

Exit Sub
EH:
    Dim de As DAO.Error
    Debug.Print "AccessErr:", Err.Number, Err.Description
    For Each de In DBEngine.Errors
        Debug.Print "ODBC:", de.Number, de.Description
    Next
    Resume Next

このコードを実行するとイミディエイトウィンドウにDebugの文言が表示されるため、それらを確認しエラーを解消していきましょう。

AccessErr: 3146 ODBC–呼び出しが失敗しました。

ODBC: 904 [Oracle][ODBC][Ora]ORA-00904: “M”.”シリアル番号”: 無効な識別子です。

上記のエラーはSQLに関するエラーです。

ありがち原因と即手当(Oracle)

数値変換エラー(ORA-01722 / 22018)

文字列を数値列に比較/代入している。
→ TO_NUMBER(…) をやめる/比較側を文字列にする/パラメータ型を数値に。


日付フォーマット不一致(ORA-01861/01830)

→ TO_DATE(‘2025/08/31′,’YYYY/MM/DD’) の形に統一。
パラメータなら日付型として渡す。


列名/権限/存在しない列(ORA-00904/942)

→ スキーマ接頭辞や別名の付け間違いを修正。


タイムアウト(SQLSTATE HYT00/HYT01)

→ クエリのプロパティ「ODBC タイムアウト」を 0 か 300 に。
VBAなら:CurrentDb.QueryDefs(“クエリ名”).ODBCTimeout = 300
インデックス・WHEREの見直し、パススルー化も有効。


意制約/NULL など(ORA-00001 / 01400 / 01438)

→ 入力値・桁数・NULL許可を確認。更新なら dbSeeChanges を付けて再実行。

ありがち原因と即手当(SQLserver)

Invalid column name

→ OracleのORA-00904と同じ。テーブルに存在しない列を参照。
→ 対策:新しい列を追加した場合、ODBC経由のリンクテーブルを再リンクする。


ODBC timeout

→ 複雑なJOINやインデックス不足で処理が終わらずタイムアウト。
→ 対策:

  • クエリのWHERE条件に適切なインデックスを作成
  • Access側では「ODBCタイムアウト」プロパティを延長(デフォルト60秒 → 300秒など)

データ型不一致

→ SQL Serverは型が厳密。Accessの「Yes/No」や「Date/Time」と食い違うと失敗。
→ CAST/CONVERTで揃える。

ありがち原因と即手当(MySQL / PostgreSQL)

Unknown column / Invalid identifier

→ Oracle/SQLServerと同じで、列名・大文字小文字の違いも要注意(特にPostgreSQLはダブルクォートで囲むと大小区別)。


文字コード不一致

→ Accessから日本語を扱う場合に「文字化け」「呼び出し失敗」が発生することあり。
→ DSN設定やODBCドライバで UTF-8 → SJIS 変換の調整が必要。

共通

対象DBで直接SQL実行して動作確認(SSMS, SQL*Plus, psql, etc.)。
→ DBで通るならAccessのSQL生成やリンクテーブル定義に問題。

リンクテーブルの再作成(新しい列を認識させる)。

列名に日本語・スペース・予約語を使わない
→ ダブルクォートや角括弧で囲む必要が出て失敗しやすい。

ODBCドライバのバージョン確認(古いDriverだと新しい型に対応していない)。

まとめ

どうでしたでしょうか?
エラーや状況によって多岐にわたるため一概にこうすれば解決するというものでもないですが、先頭に書いたコードを使用し本来のエラーを確認するだけでも、簡単に解決するかもしれません。

他にもVBAやDBの記事もございますのでご参考になれば幸いです。

タイトルとURLをコピーしました