使用 PDO 调用带有 Out 参数的存储过程
Posted
技术标签:
【中文标题】使用 PDO 调用带有 Out 参数的存储过程【英文标题】:Calling stored procedure with Out parameter using PDO 【发布时间】:2012-11-03 04:35:10 【问题描述】:我使用 PDO 已经有一段时间了,我正在重构一个项目,以便它使用存储过程而不是内联 SQL。我收到一个无法解释的错误。我使用的是 php 5.3.5 版和 mysql 5.0.7 版。
我只是想获得一个带有输出的基本存储过程。这是存储过程:
DELIMITER //
CREATE PROCEDURE `proc_OUT` (OUT var1 VARCHAR(100))
BEGIN
SET var1 = 'This is a test';
END //
这是我用来调用 proc 的代码,$db 是 PDO 的一个实例:
$stmt = $db->prepare("CALL proc_OUT(?)");
$stmt->bindParam(1, $return_value, PDO::PARAM_STR, 4000);
// call the stored procedure
$stmt->execute();
echo $returnvalue;
简单吧?但是,它会导致以下错误:
exception 'PDOException' with message 'SQLSTATE[42000]: Syntax error or access violation: 1414 OUT or INOUT argument 1 for routine mydb.proc_OUT is not a variable or NEW pseudo-variable in BEFORE trigger
如果我像这样直接调用 proc:
CALL proc_OUT(@res);
SELECT @res;
它按预期工作,这让我相信 PHP 调用它的方式存在问题,但我似乎无法找到问题所在。我按照the manual 中的说明进行操作,但仍然收到此错误。谁能建议我做错了什么?任何建议将不胜感激。非常感谢!
【问题讨论】:
***.com/a/4502524/815386 我已经用 mysql 5.5.28 和 php 5.3.10 复制了这个。此外,您似乎有两个版本的$return_value
- 另一个没有下划线。这是故意的吗?似乎对输出没有影响。
【参考方案1】:
这里似乎有一个错误,我找到的最佳解决方案是:
http://www.php.net/manual/en/pdo.prepared-statements.php#101993
来自上面链接的评论:
$dbh->query("CALL SomeStoredProcedure($someInParameter1, $someInParameter2, @someOutParameter)"); $dbh->query("SELECT @someOutParameter"); // OR, if you want very much to use PDO.Prepare(), // insert "SELECT @someOutParameter" in your stored procedure and then use: $stmt = $dbh->prepare("CALL SomeStoredProcedure(?, ?)"); $stmt ->execute(array($someInParameter1, $someInParameter2));
另请参阅:https://***.com/a/4502524/815386
【讨论】:
这里不是对 SQL 注入有威胁吗? 可能,代码只是一个例子,不要按原样使用;第二个例子应该是安全的。【参考方案2】:您需要指定您的参数是 IN/OUT 样式,如 PHP 网站示例:
http://php.net/manual/en/pdo.prepared-statements.php 示例#5
<?php
$stmt = $dbh->prepare("CALL sp_takes_string_returns_string(?)");
$value = 'hello';
$stmt->bindParam(1, $value, PDO::PARAM_STR|PDO::PARAM_INPUT_OUTPUT, 4000);
// call the stored procedure
$stmt->execute();
print "procedure returned $value\n";
【讨论】:
感谢您的回复。我的存储过程没有输入/输出参数,它只是一个输出参数,如您链接的页面上的示例 #4 我的错误。看看这里danstraw.com/…这可能是一个 MySQL 错误 似乎已针对 MySQL 5.5.3+ 和 6.0.8+ 版本修复。可以升级吗?【参考方案3】:知道了!只需添加一个
SELECT @outputparam;
在存储过程的末尾,其中@outputparam 是用于存储过程定义中的参数的名称。如果您无法编辑存储过程,您应该使用 PHP PDO 为 SELECT @outputparam 执行第二次查询以获取输出参数值。
提示:如果您使用已弃用的 DBLib 连接到 SQL Server 并按照建议修改了存储过程,您还需要调整语法以获取调用 PHP 脚本中的输出参数值:
$out = 0;
$sth = $db->prepare("DECLARE @myout INT; EXECUTE mysp :firstparam, :secondparam, @myout OUTPUT;"); // the DECLARE trick is needed with DBLib
$sth->bindParam(':firstparam', $firstparam, PDO::PARAM_INT);
$sth->execute();
$sth->bindColumn(1, $out, PDO::PARAM_INT);
$sth->fetch(PDO::FETCH_BOUND);
var_dump($out); // works
【讨论】:
以上是关于使用 PDO 调用带有 Out 参数的存储过程的主要内容,如果未能解决你的问题,请参考以下文章
使用自定义 ItemReader 调用带有 IN 和 OUT 参数的存储过程