使用 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 参数的存储过程

PHP PDO / 从 MySQL 存储过程中检索 OUT 参数

从 PHP PDO 调用 SQL 存储过程

PHP PDO 无法获取 OUT 参数值

php调用oracle带有out参数的存储过程

使用 PDO 从 PHP 调用存储过程到使用 INPUT 参数的 MYSQL Server