Laravel 10调用SQL Server存储过程如何获取输出参数
解决Laravel 10调用SQL Server存储过程获取输出参数的问题
问题核心
你的代码无法获取存储过程的输出参数,主要原因是没有正确声明输出参数的类型,且存在SQL拼接错误、重复执行查询的问题。以下是修正方案:
错误点分析
- 错误使用
Db::select():这个方法会直接执行SQL并返回结果,后续再用PDO prepare属于重复操作,破坏了参数绑定逻辑。 - 输出参数未标记
OUTPUT:存储过程中@pSuccessFlag和@pMessage是输出参数,但SQL调用里没有明确声明OUTPUT关键字,SQL Server不会返回这些参数的值。 - 参数拼接不规范:直接拼接
null或字符串会导致语法错误,且存在SQL注入风险,应该用PDO参数绑定。
修正后的完整代码
public function login(Request $request) { $conn = DB::connection('sqlsrv'); $pdo = $conn->getPdo(); // 构造存储过程调用SQL,明确标记输出参数为OUTPUT $sql = <<<SQL SET NOCOUNT ON; EXEC sp_Login @pSuccessFlag = ?, @pMessage = ?, @pCallingPage = ?, @pOperation = ?, @pid = ?, @puname = ?, @ppassword = ?, @premark = ?, @POpwd = ?, @PROLE_ID = ?, @PIS_ACTIVE = ?, @POTP = ?, @POTP_DATE = ?, @PFACILITY_ID = ?, @PCREATED_BY = ?, @PCREATED_ON = ?, @PMODIFIED_BY = ?, @PMODIFIED_ON = ?, @PUSER_TYPE_ID = ?, @PEMP_ID = ?, @PSERVER_LOGTIME = ?; SQL; $stmt = $pdo->prepare($sql); // 绑定输出参数:指定参数类型为输出,设置长度匹配存储过程定义 $successFlag = null; $message = null; $stmt->bindParam(1, $successFlag, PDO::PARAM_STR | PDO::PARAM_INPUT_OUTPUT, 2); $stmt->bindParam(2, $message, PDO::PARAM_STR | PDO::PARAM_INPUT_OUTPUT, 2000); // 绑定输入参数(测试用硬编码值) $stmt->bindValue(3, 'Login'); $stmt->bindValue(4, 'GetAll_for_login'); $stmt->bindValue(5, null); $stmt->bindValue(6, 'admin'); $stmt->bindValue(7, '55e01f2a13f587e1e9e4aedb8242d'); $stmt->bindValue(8, null); $stmt->bindValue(9, null); $stmt->bindValue(10, null); $stmt->bindValue(11, null); $stmt->bindValue(12, null); $stmt->bindValue(13, null); $stmt->bindValue(14, null); $stmt->bindValue(15, null); $stmt->bindValue(16, null); $stmt->bindValue(17, null); $stmt->bindValue(18, null); $stmt->bindValue(19, null); $stmt->bindValue(20, null); $stmt->bindValue(21, null); $stmt->execute(); // 处理多个结果集 $res = []; do { $rows = $stmt->fetchAll(PDO::FETCH_ASSOC); $res[] = $rows; } while ($stmt->nextRowset()); // 执行完成后,输出参数会被赋值 return $this->sendResponse('Done', [ 'maindata' => $res, 'param1' => $successFlag, 'param2' => $message ]); }
关键说明
SET NOCOUNT ON:必须保留,否则SQL Server会返回额外的计数结果,干扰结果集的遍历。bindParam输出参数绑定:- 第三个参数
PDO::PARAM_STR | PDO::PARAM_INPUT_OUTPUT标记该参数为输入输出类型 - 第四个参数是参数的最大长度,必须和存储过程中定义的
VARCHAR(2)、VARCHAR(2000)匹配
- 第三个参数
- 参数绑定顺序:必须和SQL中的
?占位符顺序严格对应 - 结果集遍历:通过
nextRowset()切换到下一个结果集,确保获取所有返回的数据
之前报错写法的问题修复
你之前的报错写法存在语法错误(@POTP_DATE后面少了=),且同样没有正确绑定输出参数。用上面的参数绑定方式可以彻底避免这类语法问题,同时防止SQL注入。
内容的提问来源于stack exchange,提问作者Vaibhav K. Patil
相关产品推荐
相关产品推荐

