【実務・中級編】QueryDefのSQLプロパティを動的に書き換える際の「構文エラー」をVBAで事前検知するバリデーター作成 – Access VBA解析バイブル

スポンサーリンク

Access VBAの「動的SQL」に潜む地雷を排除する:QueryDefバリデーターの極意

Access開発の現場で、`QueryDef`を動的に書き換えて運用しているエンジニアは多いだろう。しかし、その実装が「実行時エラーが発生するまでバグに気づけない」という脆弱性を孕んでいるとしたら、それはエンジニアとしてあまりに無防備だ。

SQLを文字列として結合し、それを`QueryDef`に流し込む。一見簡単そうに見えるが、タイポ、クォーテーションの閉じ忘れ、予約語の競合など、動的SQLには常に「未知の爆弾」が隠されている。

今回は、伝説的アーキテクトの視点から、「実行前にSQLの正当性を証明するバリデーター」の実装指針を授ける。

—

1. なぜ「実行時エラー」に頼ってはいけないのか

初心者はコードを書き、実行し、エラーが出たら修正する。このサイクルを繰り返す。だが、業務システムにおいて「エラーが発生して初めて問題が判明する」という状態は、運用リスクの塊だ。

特に`QueryDef`の`.SQL`プロパティを書き換える場合、Accessは「定義を更新した瞬間」ではなく「クエリを実行した瞬間」に初めて構文解析を行う。つまり、エラーが発覚するのが、ユーザーがボタンを押したその瞬間である可能性が高い。

これを防ぐには、「定義を確定させる前に、Accessのエンジンに構文チェックを代行させる」というプロキシ(代理)戦略が必要になる。

—

2. 「一時クエリ」を活用した構文チェックの設計

SQLが正しいかどうかを判断する唯一の正当な審判は、Accessのクエリエンジンだ。本番の`QueryDef`を汚さず、かつ正確にチェックするには、「チェック専用の使い捨てQueryDef」を生成し、そこにSQLを流し込んで例外をキャッチするのが最も堅牢だ。

実装コード:SQLバリデーター

この関数は、SQLを引数に受け取り、それが構文的に正しいか否かをブール値で返す。

‘ @description SQL構文の妥当性を検証するバリデーター
‘ @param strSQL 検証対象のSQL文字列
‘ @return 構文が正しければTrue、エラーがあればFalse
Public Function ValidateSQL(ByVal strSQL As String) As Boolean
Dim db As DAO.Database
Dim qdfTemp As DAO.QueryDef

Set db = CurrentDb

‘ 構文チェック用のダミー名を設定
Const TEMP_QDF = “tmp_Validation_Check”

On Error Resume Next
‘ 既存のダミーがあれば削除
DoCmd.DeleteObject acQuery, TEMP_QDF
On Error GoTo 0

On Error GoTo ErrorHandler

‘ 一時的なQueryDefを作成し、SQLをセット
‘ ここでSQLの構文解析がトリガーされる
Set qdfTemp = db.CreateQueryDef(TEMP_QDF, strSQL)

‘ 成功すればTrue
ValidateSQL = True

Cleanup:
On Error Resume Next
qdfTemp.Close
DoCmd.DeleteObject acQuery, TEMP_QDF
Set qdfTemp = Nothing
Exit Function

ErrorHandler:
‘ 構文エラー時はここに飛ぶ
Debug.Print “SQL構文エラー検出: ” & Err.Description
ValidateSQL = False
Resume Cleanup
End Function

—

3. 実務で「負けない」ための3つの鉄則

このバリデーターを導入するだけではまだ甘い。真のプロフェッショナルは、以下の3点を意識してSQLを構築する。

① 文字列連結の「クリーンルーム」を用意する

SQL構築時に、`”SELECT FROM Table WHERE ID = ” & Me.txtID` のような直書きは避けるべきだ。SQL構築専用のクラスを作成し、そこですべてのエスケープ処理とバリデーションを完結させる設計にせよ。

② パラメータークエリへの回帰

可能な限り動的SQLを避け、`PARAMETERS`句を使用した固定クエリをベースにし、`QueryDef.Parameters`コレクション経由で値を渡せ。これが「SQLインジェクション」と「構文エラー」の両方を防ぐ最もエレガントな解法だ。

③ トランザクションと分離

動的SQLを実行する際は、必ず`DAO.Database`のトランザクション制御、あるいは排他制御を考慮せよ。バリデーションを通ったSQLであっても、テーブルのロックや接続状態によって実行時エラーは起こりうる。

—

結論:技術は「守り」から固める

「動的にSQLを組み立てる」という行為は強力だが、同時に最もバグを生みやすい。今回紹介したバリデーターは、単なるエラーチェックではなく、「開発者の無意識なタイポを、実行前に矯正する仕組み」である。

業務システムで最も高価なのは、デバッグにかかる時間ではなく、ユーザーの信頼を損なう停止時間だ。
コードを書く前に、まず「どうすればエラーを未然に検知できるか」を自問せよ。それが、君が伝説的なエンジニアへと歩むための最初の一歩だ。

さあ、コードを改善しよう。君のシステムは、もっと堅牢になれる。

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