にむぞノート

新米プログラマーです。 仕事、 趣味で得た知識を適当に残していきます。

ログに出力されるSQL文にバインド変数を入れ込むバッチ処理

仕事先で製品のテストをする際、
「あれ、DBから結果が得られない?」てなった時は、
ログに出力されるSQL文をDBのコマンド実行で動かして
どの部分でダメになっているのかを特定しています。

ただ、プログラム上で実行されるSQL文とバインド変数が
別々になって出力されるので、いちいち置き換えていくのが面倒です。

↓例えば、こんな感じに。。。 (ログでは、SQL文は1行で出力されますが、見やすさを考慮して改行しています。)

SELECT * 
FROM sample_table AS t0
 WHERE user_id IN (?, ?, ?, ?, ?, ?, ?)
 AND checked_flag = ?

BIND: [101, 102, 103, 104, 105, 106, 107, 0]

これを、コマンド実行できる状態にしようと思ったら、
1、SQL文を全選択し、? を '?' に置換する。
2、1番目の ? を 101 に書き換える。
3、2番目の ? を 102 に書き換える。
(8番目の ? まで書き換えを繰り返す。)

となり、けっこう時間が取られます。
それに、バインド変数が多ければ多いほどかなり時間が取られてしまいます。

よって、バッチ処理を作成して、自動化しようと思ったのが今回の本題です。
私はよくWindows上で自動化する際はバッチファイルを使っていたのですが、
今回の場合、処理する値に右括弧があり、
for文やif文で括弧を使用した際、変数の値に右括弧がある時点で
制御文が終了されてしまう不具合に悩まされそうだったので、
VBScriptを作成することにしました。

以下、ソースコードです。

Option Explicit

Dim query, bind, prompt, title, ins, delims

title = "AutoCreateQuery"
ins = "?"
delims = ","

'ユーザーからSQL文とバインド変数の情報を取得
prompt = "SQL文を入力してください。" & VbCrLf _
        & "バインド変数の挿入先は """ & ins & """ となります。"
query = InputBox(prompt, title)
ExecQuit(query)

prompt = "バインド変数を入力してください" & VbCrLf _
        & "区切り文字は """ & delims & """ です。"
bind = InputBox(prompt, title)
ExecQuit(bind)

bind = bind & ""

'SQL文とバインド変数を各デリミタごとに配列化
Dim aryQuery, aryBind
aryQuery = Split(query, ins)
aryBind = Split(bind, delims)

'SQL文にバインド変数を挿入する
Dim concQuery
Dim i
For i = 0 To UBound(aryBind) Step 1
    concQuery = concQuery + aryQuery(i) + "'" + Trim(aryBind(i)) + "'"
Next
concQuery = concQuery + aryQuery(UBound(aryQuery))

'クリップボードにコピーし、結果を出力する
SetClipBrd(concQuery)

MsgBox "クリップボードに以下のテキストをコピーしました。" & VbCrLf _
        & VbCrLf _
        & concQuery , _
        vbOKOnly , _
        title

'Windowsコマンドでクリップボードに保管
Public Sub SetClipBrd(ByVal str)
    Dim cmd
    cmd = "cmd /c echo " & str & "| clip"
    CreateObject("WScript.Shell").Run cmd, 0
End Sub

'OK以外のボタン操作の場合、処理を終了する
Public Sub ExecQuit(ByVal str)
    If IsEmpty(str) Then
        WScript.Quit
    ElseIf str = "" Then
        MsgBox "何も入力されていません。", vbOKOnly, title
        WScript.Quit
    End If
End Sub

VBScriptはバッチファイルの後継として導入されたスクリプト言語ですが、
Windows10からのブラウザ、EdgeやIE11からはサポート対象外とされており、
段々と使用できる環境がなくなってきそうなツールです。
ですが、こういった分岐処理が多いバッチ処理やダイアログボックスを出したいといった場合は、
まだまだ便利に使えるかもしれませんね。