【Access VBAの極意】SQLインジェクションを撲滅せよ!ADO Commandオブジェクトで実現する「鉄壁のデータ操作」
こんにちは。システム開発の現場で長年、数多のAccessデータベースと向き合ってきたエンジニアです。
皆さんは、SQL文を組み立てる際に「文字列連結」をしていませんか?
`”SELECT FROM T_User WHERE UserID = ‘” & Me.txtID & “‘”`
もしそうなら、今すぐその手を止めてください。それは、あなたのシステムに「鍵をかけずに玄関を開けておく」のと同じくらい危険な行為です。
今日は、マクロの記録から脱却し、プロフェッショナルなエンジニアとして一歩先へ進むための「ADO Commandオブジェクト」と「パラメータクエリ」の極意を伝授します。
—
1. なぜ「文字列連結」は悪なのか?
初学者が最初に陥る罠が、SQL文を文字列として連結することです。これには2つの致命的な問題があります。
- SQLインジェクションのリスク: 悪意のあるユーザーが入力欄に `’ OR ‘1’=’1` などと入力すると、SQLが改ざんされ、全データが流出したり削除されたりする可能性があります。
- 型変換の地獄: 日付型や数値型を文字列として連結しようとすると、`#`や`’`の扱いでエラーが多発します。「デバッグでSQL文を眺める」という非生産的な作業に時間を浪費することになります。
これらを一撃で解決するのが、「パラメータクエリ」という考え方です。
—
2. パラメータクエリの仕組み:図解的イメージ
パラメータクエリとは、SQLのひな形(テンプレート)を先に用意し、後から「値」を流し込む仕組みです。
1. SQLの型: `SELECT FROM T_User WHERE UserID = ?`
2. パラメータ設定: `?` の場所に「この値は数値だよ」「これは安全な文字列だよ」と教える。
3. 実行: 安全な状態でデータベースが処理を行う。
この「?」が、SQLインジェクションという名のウイルスを遮断する、強固な防波堤となるのです。
—
3. 実践:ADO Commandオブジェクトによる安全な実装
さあ、現場でそのまま使えるコードを見ていきましょう。DAOではなく、柔軟性と拡張性に優れたADOを使用します。
Public Sub SafeUpdateUser(ByVal userID As Long, ByVal userName As String)
Dim conn As ADODB.Connection
Dim cmd As ADODB.Command
‘ 接続設定:カレントデータベースを指定
Set conn = CurrentProject.Connection
Set cmd = New ADODB.Command
With cmd
.ActiveConnection = conn
‘ SQL文のひな形。値を直接埋め込まず「?」を使うのがポイント!
.CommandText = “UPDATE T_User SET UserName = ? WHERE UserID = ?”
.CommandType = adCmdText
‘ パラメータの追加(順序が重要です)
‘ CreateParameter(名前, データ型, 方向, サイズ, 値)
.Parameters.Append .CreateParameter(“pName”, adVarWChar, adParamInput, 50, userName)
.Parameters.Append .CreateParameter(“pID”, adInteger, adParamInput, , userID)
‘ 実行
.Execute
End With
‘ 後始末(接続を閉じるのは重要)
Set cmd = Nothing
Set conn = Nothing
MsgBox “更新が完了しました。”, vbInformation
End Sub
コードのポイント解説
- `CurrentProject.Connection`: 現在のAccessファイルに直接接続します。これだけでDAOにはないADOの柔軟性が手に入ります。
- `CreateParameter`: ここが魂です。データの型(adVarWCharやadInteger)を明示的に指定することで、SQLエンジンは入力値を「プログラムコード」ではなく「純粋なデータ」としてのみ処理します。これがSQLインジェクションに対する最強の防衛策です。
—
4. 陥りやすいエラーとその解決策
初めてADOを扱う際に、よくあるエラーを挙げておきます。
- 「パラメータの数が足りません」エラー
- 原因:SQL文中の`?`の数と、`Parameters.Append`した回数が一致していません。
- 対策:SQL文を書き換えたら、必ずパラメータの順序と数を見直してください。
- 「型が一致しません」エラー
- 原因:`adInteger`を指定しているのに文字列を渡そうとしています。
- 対策:データベースのテーブル設計と、VBAのデータ型を一致させましょう。
—
最後に:プロへのステップアップ
いかがでしたか?文字列連結でSQLを作るのはもう終わりです。
「パラメータクエリ」を使いこなせるようになると、あなたの書くVBAコードは、ただ「動くもの」から「堅牢で保守しやすい資産」へと進化します。
Access VBAは古いと言われがちですが、ADOを使いこなす能力は、Web開発など他の言語の世界でもそのまま通用する「普遍的なエンジニアリングスキル」です。
ここをクリアすれば、あなたはもう脱・初学者。自信を持って、次の開発現場へ進んでください。応援しています!
