【入門編】【SQL Server 連携】ストアドプロシージャの出力パラメータと戻り値を VBScript から正確に受け取る ADODB 実装 – VBScript (Visual Basic Scripting Edition)解析バイブル

スポンサーリンク
スポンサーリンク

VBScriptを掌握する極限の知見:SQL Serverとの「真の対話」を実現するADODB.Command完全攻略

こんにちは。現場の泥臭い自動化から、大規模システムのアーキテクチャ設計までを渡り歩いてきた、あなたの先輩エンジニアです。

これまで「マクロの記録」や、ネットに転がっている「`Connection.Execute(“SELECT …”)`」のような断片的なコードで、なんとか業務を回してきたかもしれません。もちろん、それで動くならそれは立派な成果です。

しかし、あなたがもし「プロフェッショナルな自動化エンジニア」を目指すなら、避けては通れない壁があります。それは、「データベース側の複雑なロジック(ストアドプロシージャ)と、いかにして高精度に、かつ効率的にデータをやり取りするか」という問いです。

単にSQL文を文字列として投げつけるだけでは、データベースが計算した「戻り値」や、処理結果として返される「出力パラメータ」をスマートに受け取ることができません。

今日は、VBScriptの真の力を引き出すための鍵、`ADODB.Command` オブジェクトを駆使した、ストアドプロシージャとの高度な連携術を伝授しましょう。ここをクリアすれば、VBScriptの基本はバッチリですよ。

1. なぜ `Execute` だけでは足りないのか?

多くの初学者が最初に使うのは、`Connection.Execute` メソッドです。

' ―― 避けるべき「初級者」の書き方 ――
conn.Execute "EXEC GetUserStatus 101"

この書き方は、SQL文を「ただの文字列」として投げているに過ぎません。これでは、ストアドプロシージャが「処理が成功したかどうかのステータス(戻り値)」を返してくれていても、VBScript側でそれをキャッチする術がありません。

また、複数の値(例えば、計算結果の合計値や、エラーコードなど)を「出力パラメータ」として受け取りたい場合、この方法では非常に困難、あるいは不可能です。

そこで登場するのが、`ADODB.Command` オブジェクトです。これは、SQL文を単なる文字列としてではなく、「定義されたインターフェース(型や方向性を持った命令)」として扱うための、いわば「高度な通信プロトコル」なのです。

2. Commandオブジェクトの三要素:Input, Output, Return

ストアドプロシージャとの対話には、3つの役割のパラメータが存在します。これらを正しく設計できるかどうかが、アーキテクトへの第一歩です。

要素 役割 VBScriptでの扱い
Input Parameter プロシージャに渡す引数 `adParamInput` を指定
Output Parameter プロシージャが計算して返す値 `adParamOutput` を指定
Return Value プロシージャの実行完了ステータス `adParamReturnValue` を指定

これらをバラバラに扱うのではなく、`Command` オブジェクトという一つのコンテナに格納して、一括で実行する。これがプロの作法です。

3. 【実践】ストアドプロシージャ連携の完全実装例

それでは、具体的なシナリオを想定してみましょう。

【シナリオ】
SQL Server側に `usp_CalculateBonus` というストアドプロシージャがあるとします。

  • 入力: `EmployeeID` (整数)
  • 出力: `BonusAmount` (通貨/浮動小数点)
  • 戻り値: 処理の成否 (0なら成功、それ以外はエラーコード)

これをVBScriptから完璧に呼び出すコードを書いていきます。

事前準備:SQL Server側の定義(イメージ)

CREATE PROCEDURE usp_CalculateBonus
    @EmployeeID INT,
    @BonusAmount MONEY OUTPUT
AS
BEGIN
    -- 何らかの複雑な計算ロジック...
    IF @EmployeeID <= 0 RETURN -1; -- エラーコードを返す
    
    SET @BonusAmount = 5000.0;     -- 出力パラメータに値をセット
    RETURN 0;                      -- 成功ステータスを返す
END

VBScript 実装コード

Option Explicit

' --- 定数定義 (ADODBの列挙型を直接書くことで、参照設定なしでも動作させる) ---
Const adCmdText = 1
Const adParamInput = 1
Const adParamOutput = 2
Const adParamReturnValue = 125  ' 戻り値用の特殊な定数
Const adInteger = 3
Const adCurrency = 6
Const adVarChar = 200

' ---------------------------------------------------------
' メイン処理
' ---------------------------------------------------------
Dim conn, cmd
Dim empID, bonus, retVal
Dim errCode

empID = 101 ' テスト用の社員ID

' 1. Connectionオブジェクトの生成と接続
Set conn = CreateObject("ADODB.Connection")
On Error Resume Next ' エラーハンドリングの開始
conn.Open "Provider=SQLOLEDB;Data Source=YOUR_SERVER;Initial Catalog=YOUR_DB;Integrated Security=SSPI;"

If Err.Number <> 0 Then
    WScript.Echo "接続エラー: " & Err.Description
    WScript.Quit
End If
On Error GoTo 0 ' エラーハンドリングを通常に戻す

' 2. Commandオブジェクトの構築
Set cmd = CreateObject("ADODB.Command")
Set cmd.ActiveConnection = conn
cmd.CommandText = "usp_CalculateBonus"
cmd.CommandType = adCmdText ' ストアド名はテキストとして扱う

' 3. パラメータの定義(ここが心臓部です!)
' ※定義する順番は、SQL Server側のプロシージャの引数順と完全に一致させる必要があります。

' (A) 戻り値 (ReturnValue) を最初に定義
Set retVal = cmd.CreateParameter("@ReturnVal", adInteger, adParamReturnValue)
cmd.Parameters.Append retVal

' (B) 入力パラメータ (Input)
Set empID = cmd.CreateParameter("@EmployeeID", adInteger, adParamInput, , empID)
cmd.Parameters.Append empID

' (C) 出力パラメータ (Output)
' 第4引数はサイズ、第5引数は値。出力の場合はサイズ指定が重要です。
Set bonus = cmd.CreateParameter("@BonusAmount", adCurrency, adParamOutput)
cmd.Parameters.Append bonus

' 4. 実行
On Error Resume Next
cmd.Execute

If Err.Number <> 0 Then
    WScript.Echo "実行エラー: " & Err.Description
Else
    ' 5. 結果の回収
    ' 実行後、Parametersコレクションから値を取り出します
    retVal = cmd.Parameters("@ReturnVal").Value
    bonus = cmd.Parameters("@BonusAmount").Value

    If retVal = 0 Then
        WScript.Echo "【成功】"
        WScript.Echo "社員ID: " & empID
        WScript.Echo "ボーナス額: " & FormatCurrency(bonus)
    Else
        WScript.Echo "【プロシージャ内エラー】コード: " & retVal
    End If
End If
On Error GoTo 0

' 6. 後片付け (オブジェクトのライフサイクル管理)
cmd.Unbind ' パラメータの紐付け解除
Set cmd = Nothing
conn.Close
Set conn = Nothing

WScript.Echo "処理が完了しました。"

4. アーキテクトが教える「陥りやすい罠」と回避術

この実装をマスターする上で、多くのエンジニアが躓く「二つの罠」を教えておきましょう。

罠その1:パラメータの順序と型

`Command.Parameters.Append` で追加していく順番は、SQL Server側のプロシージャ定義の順番と一字一句、一型一句違わずに一致させなければなりません。
また、出力パラメータ(`adParamOutput`)の場合、データ型(`adVarChar` など)によっては「サイズ(Length)」を正しく指定しないと、値が切り捨てられたり、実行時にエラーが発生したりします。

罠その2:結果セット(SELECT)との混在(最重要!)

ここが最も「伝説のエンジニア」としての知見が必要な部分です。
もし、ストアドプロシージャの中で `SELECT` 文を実行して結果セットを返し、かつ `OUTPUT` パラメータも持っている場合、注意が必要です。

ADODBの仕様上、「結果セット(Recordset)をすべて読み終えるか、あるいは明示的に閉じるまで、出力パラメータの値は `Null` のままになる」 という性質があります。

' もしプロシージャが SELECT を返すなら...
Set rs = cmd.Execute
Do While Not rs.EOF
    ' データを読み込む
    rs.MoveNext
Loop
rs.Close ' ← これをしないと、以下の値は取得できない!

' その後に初めてパラメータが有効になる
bonus = cmd.Parameters("@BonusAmount").Value

「コードは合っているはずなのに、出力パラメータがなぜか空っぽだ……」と悩んだときは、この「結果セットの残存」を疑ってください。

最後に

いかがでしたか?
`ADODB.Command` を使いこなすことは、単なるコードの書き換えではありません。データベースとプログラムの境界線を、プロフェッショナルな「契約(インターフェース)」として設計することなのです。

最初はパラメータの型指定や順序に苦労するかもしれません。しかし、この「厳格さ」こそが、大規模な業務システムにおけるデータの整合性を守るための武器になります。

ここをクリアすれば、VBScriptの基本はバッチリですよ。自信を持って、次の自動化プロジェクトに挑んでくださいね。応援しています!

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