15

我已经使用 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 调用它的方式存在问题,但是我似乎找不到问题所在。我按照手册中的说明进行操作,但仍然出现此错误。谁能建议我做错了什么?任何建议将不胜感激。非常感谢!

4

3 回答 3

13

似乎这里有一个错误,我发现的最佳解决方案是:

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 ://stackoverflow.com/a/4502524/815386

于 2012-11-17T16:47:08.973 回答
6

知道了!只需添加一个

SELECT @outputparam;

at the end of the stored procedure, where @outputparam is the name used for the param in the stored procedure definition. If you cannot edit the stored procedure, you should do a second query, for SELECT @outputparam, with PHP PDO to get the output param value.

Tip: If you're using the deprecated DBLib to connect to SQL Server and you modified the stored procedure as suggested, you'll also need to tweak your syntax to get the output param value in the calling PHP script:

$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
于 2015-08-26T10:34:55.877 回答
5

您需要指定您的参数是 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";
于 2012-11-17T16:48:11.390 回答