You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在PHP中获取SQL Server存储过程的输出结果

解决SQL Server存储过程在PHP中获取多结果集与输出参数的问题

你的核心问题是没有正确遍历存储过程返回的所有结果集,同时当前SQL写法可优化,直接通过PHP绑定输出参数更高效,无需额外执行select语句。以下提供两种解决方案:

方案一:直接通过PHP绑定输出参数(推荐)

无需在SQL里声明变量和额外select,直接让PHP绑定存储过程的输出参数,跳过中间无关结果集后获取参数值,还能避免SQL注入风险。

调整后的SQL语句

EXEC dbo.Precio ?, ?, ?, ?, ?, ?, ?, ?

对应的PHP代码

// 定义输入输出参数初始值
$IDCliente = 123; // 替换为实际客户ID
$NETO = null;
$DTO1 = null;
$DTO2 = null;
$DTO3 = null;
$CODIGO = null;
$CODIGOEAN = null;
$NOMBRE = null;

// 参数数组:输入参数用SQLSRV_PARAM_IN,输出参数用SQLSRV_PARAM_OUT并指定类型
$params = [
    [$IDCliente, SQLSRV_PARAM_IN],
    [$NETO, SQLSRV_PARAM_OUT, SQLSRV_PHPTYPE_FLOAT],
    [$DTO1, SQLSRV_PARAM_OUT, SQLSRV_PHPTYPE_FLOAT],
    [$DTO2, SQLSRV_PARAM_OUT, SQLSRV_PHPTYPE_FLOAT],
    [$DTO3, SQLSRV_PARAM_OUT, SQLSRV_PHPTYPE_FLOAT],
    [$CODIGO, SQLSRV_PARAM_OUT, SQLSRV_PHPTYPE_STRING(SQLSRV_ENC_CHAR)],
    [$CODIGOEAN, SQLSRV_PARAM_OUT, SQLSRV_PHPTYPE_STRING(SQLSRV_ENC_CHAR)],
    [$NOMBRE, SQLSRV_PARAM_OUT, SQLSRV_PHPTYPE_STRING(SQLSRV_ENC_CHAR)]
];

// 准备并执行语句
$sql = "EXEC dbo.Precio ?, ?, ?, ?, ?, ?, ?, ?";
$stmt = sqlsrv_prepare($pc, $sql, $params);
if ($stmt === false) die(print_r(sqlsrv_errors(), true));
if (sqlsrv_execute($stmt) === false) die(print_r(sqlsrv_errors(), true));

// 跳过存储过程返回的第一个结果集
while (sqlsrv_next_result($stmt)) {}

// 输出参数已赋值,整理结果
$result = [
    'neto' => $NETO,
    'DTO1' => $DTO1,
    'DTO2' => $DTO2,
    'DTO3' => $DTO3,
    'CODIGO' => $CODIGO,
    'CODIGOEAN' => $CODIGOEAN,
    'NOMBRE' => $NOMBRE
];

echo json_encode($result);

方案二:正确遍历所有结果集(兼容原有SQL写法)

如果坚持保留原有SQL中的select语句,需修正遍历逻辑,确保捕获最后一个结果集:

修正后的PHP代码

$stmt = sqlsrv_prepare($pc, $sql);
if ($stmt === false) die(print_r(sqlsrv_errors(), true));
sqlsrv_execute($stmt);

$finalData = null;
// 逐个遍历所有结果集,保留最后一个结果集的数据
do {
    if ($row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC)) {
        $finalData = $row;
    }
} while (sqlsrv_next_result($stmt));

echo json_encode($finalData);

原有代码失效原因

你原有的do-while循环中,每次先fetch再调用两次sqlsrv_next_result,会跳过部分结果集,无法正确捕获最后那个select生成的结果集。修正后的循环会逐一处理所有结果集,确保拿到目标数据。


内容的提问来源于stack exchange,提问作者Cesc Teruel Villanueva

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 19:42:27