VBScriptでデータベースを叩くなら「文字列結合」を即刻やめろ:ADODB.Commandによる鉄壁のSQL構築術
業務自動化の現場でVBScriptは今なお現役だ。しかし、多くのエンジニアが「動けばいい」という甘い考えで書いたコードが、セキュリティホールという時限爆弾を抱えている事実に気づいていない。
特に、データベース連携においてSQL文を文字列結合で組み立てる手法は、SQLインジェクションという致命的な脆弱性を招く。今日は、伝説的なアーキテクトとして、この「悪しき習慣」を根絶し、`ADODB.Command` を用いた堅牢な実装へと昇華させるための極意を伝授する。
—
1. なぜ「文字列結合」は悪なのか?
初学者が陥るのが、以下のようなSQL構築だ。
‘ 絶対にやってはいけないNG例
sql = “SELECT FROM Users WHERE UserName = ‘” & userInput & “‘”
もし `userInput` に `’ OR ‘1’=’1` が入力されたらどうなるか? 全データが流出するか、最悪の場合データベースが破壊される。これは単なるバグではない。「SQLの命令」と「データ」を混同させている構造そのものが欠陥なのだ。
このリスクを回避するための唯一の解が、パラメータ化クエリ(Parameterized Queries)である。
—
2. ADODB.Commandによる「型」と「値」の分離
`ADODB.Command` オブジェクトを使う最大の利点は、SQLテンプレートとパラメータをエンジンレベルで分離できることだ。これにより、入力された値は「単なる文字列」としてのみ解釈され、決して「SQLコマンドの一部」としては実行されない。
実装の極意:プロダクションコード
保守性と安全性を極限まで高めた実装例を示す。これをテンプレートとして活用してほしい。
Option Explicit
‘ データベース操作関数:安全な検索処理
Function GetUserData(sConnStr, sUserName)
Dim oConn, oCmd, oRS
‘ オブジェクト生成
Set oConn = CreateObject(“ADODB.Connection”)
Set oCmd = CreateObject(“ADODB.Command”)
On Error Resume Next
oConn.Open sConnStr
Set oCmd.ActiveConnection = oConn
‘ クエリのテンプレート化(? はプレースホルダ)
oCmd.CommandText = “SELECT UserID, Email FROM Users WHERE UserName = ?”
oCmd.CommandType = 1 ‘ adCmdText
‘ パラメータを明示的に追加 (型、方向、サイズ、値)
‘ adVarWChar(202), adParamInput(1)
oCmd.Parameters.Append oCmd.CreateParameter(“@UserName”, 202, 1, 50, sUserName)
‘ 実行
Set oRS = oCmd.Execute
If Not oRS.EOF Then
GetUserData = oRS(“Email”).Value
Else
GetUserData = Null
End If
‘ 後処理(リソース解放は必須)
oRS.Close
oConn.Close
Set oRS = Nothing
Set oCmd = Nothing
Set oConn = Nothing
If Err.Number <> 0 Then
WScript.Echo “Error: ” & Err.Description
End If
End Function
—
3. なぜこのコードが「強い」のか
A. 型の制約(Type Enforcement)
`CreateParameter` でデータ型(例: `202` = `adVarWChar`)を指定している点が重要だ。これにより、データベースエンジンは受け取る値を厳密に検証し、予期せぬ挙動を未然に遮断する。
B. 明示的なリソース解放
VBScriptのガベージコレクションを信用してはいけない。`Set Object = Nothing` を徹底することで、大規模なループ処理や長時間実行される自動化ツールにおけるメモリリークを防ぐ。これは、プロフェッショナルが守るべき最低限の規律だ。
C. 保守性の担保
SQL文をコードの中にハードコーディングせず、パラメータのみを差し替える構造にすることで、DBの仕様変更時にも修正箇所を最小限に抑えられる。
—
4. エンジニアへのラストアドバイス
業務自動化ツールを作る際、最も怖いのは「動くコード」ではなく「脆弱なコード」だ。
1. 入力値はすべて疑え: `CreateParameter` は、外部からの入力を安全に扱うための唯一の盾だ。
2. エラーハンドリングを怠るな: `On Error Resume Next` を使うなら、必ず `Err.Number` をチェックし、ログに残す仕組みを実装すること。
3. 複雑性を排除せよ: コードはシンプルであればあるほどバグは減る。`ADODB.Command` は一見遠回りに見えるかもしれないが、将来の「修正コスト」を激減させる賢明な投資だ。
このコードをコピー&ペーストするだけでなく、なぜこの構造が必要なのかを噛み締めてほしい。それが、スクリプターから「熟練の自動化アーキテクト」へ進化するための第一歩となる。
