如何从存储过程中获得返回值?PHP | pdo



我想显示SQL Server的SP的返回值。我试过用这种方法,但没有成功。

我正在使用PHP PDO进行数据库连接,我正在执行SQL Server存储过程。

$feesObj = new FeesConfig('config/fees.ini');
$feesConfig = $feesObj->getFeesConfig();

$studentId = $user->getSyStudentId();
$statement = $conn->prepare('exec ?= usp_GetStudentDegreeLevel ?');
$statement->bindParam(1, $retval, PDO::PARAM_STR|PDO::PARAM_INPUT_OUTPUT);
$statement->bindParam(2, $studentId, PDO::PARAM_INT);
$statement->execute();
$row = $statement->fetch(PDO::FETCH_ASSOC);
var_dump("return value". $retval);exit;

SP执行的输出

NULL

预期的结果

1

我对这段代码的错误。我正在呼叫SQL Server SP.

原始答案(使用我通常获取可能输出参数的返回值和存储过程的返回值的方法):

您可以考虑以下内容:

  • 存储过程的返回值是整数,因此需要使用适当的绑定。
  • 如果是OUTPUT参数,需要在PDOStatement::bindParam呼叫中设置maxLength参数。如文档中所述,要…如果参数是存储过程中的OUT参数,则必须显式设置长度
  • 您需要获取所有可能的结果集(使用PDOStatement::nextRowset)以获得输出参数的值。或者,在INSERTUPDATE语句的情况下,作为一个选项,将SET NOCOUNT ON作为存储过程中的第一行。正如文档中所解释的,这个语句…停止显示受Transact-SQL语句或存储过程影响的行数计数的消息作为结果集的一部分返回。

下面是一个使用SQL Server 2017, PHP 7.4.8和PHP Driver for SQL Server 5.8的简化示例:

存储过程:

CREATE PROCEDURE usp_GetStudentDegreeLevel 
@StudentId INT  
AS  
BEGIN
SELECT 'Information about the student' AS StudentInfo;
RETURN 1;
END

PHP代码:

<?php
$server   = 'serverinstance,port';
$database = 'database';
$username = 'username';
$password = 'password';
try {
$conn = new PDO("sqlsrv:server=$server;Database=$database", $username, $password);
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$conn->setAttribute(PDO::SQLSRV_ATTR_ENCODING, PDO::SQLSRV_ENCODING_SYSTEM);
} catch( PDOException $e ) {
die( "Error connecting to SQL Server".$e->getMessage());
}
try { 
// 
$sql = "EXEC ? = usp_GetStudentDegreeLevel ?";
$statement = $conn->prepare($sql);
if ($statement === false) {
echo print_r($conn->errorInfo(), true);
exit;
}
// Execution
$retval    = 0;
$studentId = 1;
$statement->bindParam(1, $retval, PDO::PARAM_INT | PDO::PARAM_INPUT_OUTPUT, PDO::SQLSRV_PARAM_OUT_DEFAULT_SIZE);
$statement->bindParam(2, $studentId, PDO::PARAM_INT);
if ($statement->execute() === false) {
echo print_r($conn->errorInfo(), true);
exit;
}   
// Fetch data. 
do {
if ($statement->columnCount() > 0) {
while ($row = $statement->fetch(PDO::FETCH_ASSOC)) {
echo print_r($row, true); 
};
};  
} while ($statement->nextRowset());
//
var_dump("Return value: " . $retval); 
$statement = null;
} catch (PDOException $e) {
echo $e->getMessage();
exit;   
}
$conn = null;
?>

结果:

Array ( [StudentInfo] => Information about the student ) string(15) "Return value: 1"

更新(一个示例,它再现了意外的返回值):

我能重现这个错误的唯一方法是:
  • 使用PDO::ERRMODE_SILENT作为默认错误处理模式
  • 存储过程错误和/或SQL语句错误。
  • No检查PDO::prepare和/或PDOStatement::execute呼叫的结果是否成功。
  • PHP代码:

// PDO object with default error handling (PDO::ERRMODE_SILENT, but for PHP version before 8.0.0)
$conn = new PDO("sqlsrv:server=$server;Database=$database", $username, $password);
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT);
$conn->setAttribute(PDO::SQLSRV_ATTR_ENCODING, PDO::SQLSRV_ENCODING_SYSTEM);
// SQL statement with error
$sql = "EXEC ? = usp_GetStudentDegreeLevel ,?";
$statement = $conn->prepare($sql);
$statement->bindParam(1, $retval,  PDO::PARAM_STR | PDO::PARAM_INPUT_OUTPUT, 1);
$statement->bindParam(2, $studentId, PDO::PARAM_INT);
$statement->execute();
$row = $statement->fetch(PDO::FETCH_ASSOC);
//
var_dump($retval); 

结果:

NULL

最新更新