sqlsrv_query执行长查询无结果无报错 直接运行SQL可返回数据
解决方案
- 调整查询超时配置
sqlsrv默认查询超时时间可能无法适配13秒的长查询场景,你可以在sqlsrv_query的第四个参数中增加QueryTimeout配置(单位为秒),按需设置足够的超时阈值:
// 将超时设为30秒,适配你的查询耗时 $query= sqlsrv_query($conn, $sql_q, array(), array( "Scrollable" => 'static', "QueryTimeout" => 30 ));
- 替换游标类型,避免计数异常
sqlsrv_num_rows的返回结果和游标类型强相关,static游标处理长查询大结果集时偶发计数为0的异常。你可以暂时去掉Scrollable参数,改用默认前向游标,直接通过sqlsrv_fetch_array判断是否有数据,无需依赖sqlsrv_num_rows:
$query= sqlsrv_query($conn, $sql_q); if ($query) { $hasResult = false; while ($result = sqlsrv_fetch_array($query)) { $hasResult = true; // 原有业务处理逻辑 } if (!$hasResult) { die(var_dump('无有效数据返回')); } }
注:如果必须使用sqlsrv_num_rows做前置判断,可以尝试将Scrollable参数值替换为buffered再测试
- 校验日期拼接与时区一致性
确认PHP脚本时区与SQL Server实例时区一致,避免动态生成的$dateDebut、$dateFin和预期值不符。你可以将拼接完成的$sql_q写入本地日志,和你手动在SQL Server中执行的语句逐字对比,排查字符转义、编码隐式转换的问题。 - 开启完整错误日志排查静默异常
部分低级别错误默认会被sqlsrv扩展静默忽略,你可以在连接数据库前增加以下配置,强制输出所有错误信息:
sqlsrv_configure("WarningsReturnAsErrors", 1); sqlsrv_configure("LogSubsystems", SQLSRV_LOG_SYSTEM_ALL); sqlsrv_configure("LogSeverity", SQLSRV_LOG_SEVERITY_ALL);
- 解决参数嗅探导致的执行计划异常
如果以上操作都无效,可能是参数嗅探导致应用端调用SQL时使用了错误的执行计划,你可以在SQL语句末尾增加OPTION (RECOMPILE)强制重新生成执行计划:
-- 在原有WHERE语句后新增 WHERE ... OPTION (RECOMPILE)
内容的提问来源于stack exchange,提问作者Renaud L.-Gagnon
相关产品推荐
相关产品推荐

