こうこく
作 ▸
改 ▸

PHPでSQLServerのストアドプロシージャを実行して出力パラメータを受け取る

PDObindParam の第三引数 (型指定してるやつ) に PDO::PARAM_INPUT_OUTPUT をぶつけて使うと、ストアドプロシージャの出力パラメータを受け取れるらしいです。

だいたい公式マニュアルの通りです。やってみました。

PHP: プリペアドステートメントおよびストアドプロシージャ - Manual

まず、下記のSQLで適当なテーブルとストアドプロシージャを作ります。

SQL
-- テーブル作成
CREATE TABLE [NANTOKA_TABLE] (
	[NANTOKA_ID] INT NOT NULL PRIMARY KEY,
	[NANTOKA_NAME] VARCHAR(20) NULL,
	[NANTOKA_TYPE] SMALLINT NULL,
);

-- データ投入
INSERT [NANTOKA_TABLE] VALUES
(100, 'kiriukun', 90),
(101, 'junkun', 91),
(102, 'yukochan', 92);

-- ストアドプロシージャ作成
CREATE PROCEDURE [NANTOKA_PROCEDURE]
	@ID INT,
	@NAME VARCHAR(20) OUTPUT,
	@TYPE SMALLINT OUTPUT
AS
	SELECT
		@NAME = [NANTOKA_NAME],
		@TYPE = [NANTOKA_TYPE]
	FROM
		[NANTOKA_TABLE]
	WHERE
		[NANTOKA_ID] = @ID
;

念のため、次のSQLでストアドプロシージャの動作確認をしておきます。

動作確認
DECLARE @RETURN_NAME VARCHAR(20);
DECLARE @RETURN_TYPE SMALLINT;
EXECUTE [NANTOKA_PROCEDURE] 100, @RETURN_NAME OUTPUT, @RETURN_TYPE OUTPUT;

PRINT(@RETURN_NAME); -- kiriukun
PRINT(@RETURN_TYPE); -- 90

最後に以下のPHPを実行して、ストアドの出力パラメータを受け取れることを確認します。

PDO からストアドを実行するときは CALL ステートメントを使います。

PHP
// 接続設定
$host = '(接続先)';
$dbname = '(DB名)';
$user = '(ユーザー名)';
$pass = '(パスワード)';

// PDOでDB接続
$dbh = new PDO("sqlsrv:server=$host; database=$dbname;", $user, $pass);
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); // エラー時に例外を吐かせる (関係ないけど)
$dbh->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE , PDO::FETCH_ASSOC); // 連想配列でfetchする (関係ないけど)

// ステートメント準備
$sth = $dbh->prepare("{ CALL NANTOKA_PROCEDURE(?, ?, ?) }");
$id = 100;
$sth->bindParam(1, $id, PDO::PARAM_INT);
$sth->bindParam(2, $name, PDO::PARAM_STR|PDO::PARAM_INPUT_OUTPUT, 20);
$sth->bindParam(3, $type, PDO::PARAM_INT|PDO::PARAM_INPUT_OUTPUT, 5);

// 実行
$sth->execute();

// bindParamの第二引数 (参照渡し) にセットされた内容を確認
var_dump($name); // string(8) "kiriukun"
var_dump($type); // int(90)

ほかに参考にしたページ

Transact-SQLでストアドプロシージャを作成する:さらっと覚えるSQL&T-SQL入門(9) - @IT

ストアド プロシージャを呼び出す | Microsoft Docs

OUTPUT パラメータを使用してデータを返す処理

この記事に何かあればこちらまで (非公開)