前回は、AccessのVBAからSqlServerのストアドプロシージャを実行するというのをやりましたが、
【SqlServer】ストアドプロシージャを使って初めての処理
今回は、
ココがポイント
Accessの方でパラメーターを付けたVBAでストアドプロシージャを実行する
ということをやってみました。
簡単だと思っていましたが結局1日手こずりしました。
SSMSでSQLコードを作成
だんだんと、SQLにも慣れてきました・・・というより、SSMS内で「新しいクエリ」からの、「エディターでクエリをデザイン」モードを使えば簡単にSQLが作成できることがわかりました。
今回は、Accessの方からパラメーター付きでSqlServerに実行させたいので、ストアドプロシージャの中にもパラメーターを埋め込みます。
ココがポイント
@arrange_idというパラメーターでデータを絞る
ような事をさせてみます。
パラメーターを設定したVBA作成
Sub shipping_schedule_calc() Dim Cnn As New ADODB.Connection Dim cmd As New ADODB.Command ' Dim param As ADODB.Parameter ' Dim strMsg As String On Error GoTo Err_shipping_schedule_calc ' Debug.Print Forms![stock_inquiry]![arrange_id] 'SQLServer接続設定&接続 With Cnn .Provider = "SQLOLEDB" .ConnectionString = "Data Source=サーバー名;" & _ "Initial Catalog=データベース名;" & _ "User ID=lユーザー名;" & _ "Password=パスワード" .Open End With 'ストアドプロシージャ呼び出し設定&呼び出し With cmd .CommandTimeout = 0 'タイムアウト設定を無制限に .ActiveConnection = Cnn 'サーバー接続設定 .CommandText = "shipping_schedule_calc_add" 'ストアド名セット .CommandType = adCmdStoredProc 'ストアドなのでadCmdStoredProc .Parameters("@arrange_id").Value = Forms![stock_inquiry]![arrange_id] '戻り値設定 ' .Parameters.Append .CreateParameter("@rtn", adInteger, adParamReturnValue) '実行※レコードは返ってこないのでadExecuteNoRecords .Execute , , adExecuteNoRecords '戻り値の判断&表示用メッセージ生成 ' If .Parameters.Item("@rtn").Value = 0 Then ' strMsg = "出荷予定数の計算は正常終了しました。" ' Else ' strMsg = "異常終了しました" & vbCrLf & _ ' "ErrNO=" & .Parameters.Item("@rtn").Value ' End If End With Exit_shipping_schedule_calc: '接続解除 Cnn.Close: Set Cnn = Nothing 'メッセージ表示 ' MsgBox strMsg Exit Sub Err_shipping_schedule_calc: ' DoCmd.Close acForm, "jobwait", acSaveNo 'ストアド以外の場所でのエラーなので、VBAのErrの情報セット ' strMsg = "異常終了しました" & vbCrLf & _ ' "ErrNO=" & Err.number & " ErrMsg=" & Err.description ' Resume Exit_shipping_schedule_calc MsgBox "エラー: " & Err.description End Sub
ちょっと上のコードは、コメントアウトが多すぎるので見ずらいとは思いますが、ポイントは、
.Parameters("@arrange_id").Value = Forms![stock_inquiry]![arrange_id]
の部分で、
フォームの値をパラメーターとして設定している
という事です。このようにして、フォームの値をストアドプロシージャに渡すことができれば、本当に便利ですよね。
VBAのエラー戻り値があるとエラー
'戻り値設定 ' .Parameters.Append .CreateParameter("@rtn", adInteger, adParamReturnValue)
コメントアウトしてある、ストアドプロシージャでエラーがあった時の戻り値の処理部分ですが、このコードを入れるとエラーになります。
私の現時点でのスキルでは何でエラーになるのかが理解できないので、コメントアウトして消す事にしました。
ストアド内でエラーが起きたら、ロールバックさせるかと思いますが、エラーがあったという事は通知されないのかもしれません。
時間があるときにもっと追及してみたいと思います。
ストアドプロシージャのコード
USE [Logistics] GO /****** Object: StoredProcedure [dbo].[shipping_schedule_calc_add] Script Date: 2020/03/14 14:05:08 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO ALTER PROCEDURE [dbo].[shipping_schedule_calc_add] @arrange_id VARCHAR(50) AS BEGIN TRY BEGIN TRANSACTION UPDATE stock SET waiting_shipping = waiting_shipping + View_shipping_schedule_calc.出荷予定数 FROM View_shipping_schedule_calc INNER JOIN stock ON View_shipping_schedule_calc.product_sku = stock.jan_sku_code WHERE View_shipping_schedule_calc.arrange_date = @arrange_id UPDATE dbo.[order] SET dbo.[order].progress = 2 WHERE dbo.[order].arrange_date = @arrange_id COMMIT TRANSACTION END TRY BEGIN CATCH ROLLBACK TRANSACTION RETURN ERROR_NUMBER() END CATCH RETURN 0
上のストアドプロシージャでの注意ポイントとしては、
@arrange_id VARCHAR(50)
といいうように、ちゃんとパラメーターの宣言をしてあげないとエラーがでます。
そして、SSMSで作成したSQLを組み込みますが、
WHERE View_shipping_schedule_calc.arrange_date = @arrange_id
の様に、「@arrange_id」のようにダイレクトに入れればいいらしく、とくにカンマやダブルコーテーションなども必要ないようです。
今まではストアドプロシージャを敬遠していましたが、ちょっと覚えればサーバー側で処理してくれるので端末側のAccessの負担が減って処理が楽になります。