将 PDO 与 MS SQL 结合使用“活动结果不包含任何字段”

Posted

技术标签:

【中文标题】将 PDO 与 MS SQL 结合使用“活动结果不包含任何字段”【英文标题】:"The active result contains no fields" using PDO with MS SQL 【发布时间】:2013-05-20 02:38:08 【问题描述】:

我正在将一些旧的 php 页面转换为使用 PDO。

以下是两个简化的查询(不是我的实际查询),以帮助理解我遇到的问题...

SELECT afield INTO #temptable FROM atable WHERE anotherfield = 'somevalue';

SELECT afield,anotherfield,onemorefield FROM atable 
WHERE afield NOT IN (SELECT * FROM #temptable);

上面的查询抛出了标题中描述的错误(更完整的是它抛出“致命错误:未捕获的异常'PDOException'并带有消息'SQLSTATE [IMSSP]:查询的活动结果不包含任何字段。'”)

如果我像这样更改查询...

with (SELECT afield INTO #temptable FROM atable 
WHERE anotherfield = 'somevalue') AS temptable;

SELECT afield,anotherfield,onemorefield FROM atable 
where afield NOT IN (SELECT * FROM temptable);

这似乎绕过了错误,但这个版本的查询效率极低,因为它似乎为另一个查询中的每个字段比较运行临时查询。

有没有办法让第一个表单(创建一次临时表)与 PDO 一起工作?

它在使用 mssql 的旧页面上运行良好。

编辑:我知道我可以通过创建一个真实的表,在 php 中运行它,然后运行第二个查询(在一个单独的 php 调用中),然后运行第三个查询以删除第一个表。但我宁愿不必诉诸于此! :)

【问题讨论】:

注意像SELECT, WHERE, FROM ...这样的SQL关键字应该大写。这将提高可读性。你应该先从这个开始 你真的用分号;分隔查询吗? 试过了。没有区别。 我没有 SQL Server,无法测试。可能是底层 sqlclient C 库有问题 【参考方案1】:

我在这个版本中使用的是 Laravel5 你应该执行

DB::select('SET NOCOUNT ON; EXEC stored_procedure'. $param1.','...$paramN);

效果很好。

【讨论】:

【参考方案2】:

我遇到了这个问题,上面的答案有所帮助,但这里的答案是假设的:

    您可以使用SET NOCOUNT ON 修改存储过程,并且您 想做这个 您确定需要移动到下一个行集 $statement->nextRowset();

在我的情况下,我使用通用方法从多个存储过程中提取数据,在这些存储过程中我可能有也可能没有这个问题,并且需要在增加行集之前进行检查。

我使用了以下内容:

while($stmt->columnCount() === 0 && $stmt->nextRowset()) 
    // Advance rowset until we get to a rowset with data


if($stmt->columnCount() > 0) 
    // We found something with data, do stuff.
    // Code here

希望这可以帮助遇到类似问题的其他人。

【讨论】:

【参考方案3】:

如果您使用 StoredProcedure 并执行以下操作:

DB::select("EXEC [storedprocedure] $param1,$param2;");

如上所述,PDO 期望 DB::select 语句返回一些数据。但是由于您的StoredProcedure 没有返回任何数据,您可以将DB::select 更改为DB::update,如下所示:

DB::update("EXEC [storedprocedure] $param1,$param2;");

在此之后,错误应该不再出现。

【讨论】:

我的 SP 仅在错误时选择了某些内容。通过选择一些关于成功的东西,我能够得到这个工作。【参考方案4】:

我正在使用 laravel5,这就是我解决问题的方法;

DB::select("SET ANSI_NULLS ON; SET ANSI_WARNINGS ON;EXEC [storedprocedure] $param1,$param2;");

【讨论】:

谢谢卡马罗。我也在 Laravel5 上,这很有帮助。我跑了DB::select('SET NOCOUNT ON; EXEC stored_procedure');,它运行良好。【参考方案5】:

如果你使用的是存储过程,那么使用

SET NOCOUNT ON 

问题是存储过程返回的结果包含受影响的行数作为第一个结果。

Microsoft Documentation

【讨论】:

我希望我在尝试我的查询之前找到了这么多不同的方式。谢谢! DB::select('SET NOCOUNT ON ; EXEC stored_procedure ') 就我而言,我没有使用存储过程,它也可以工作。【参考方案6】:

PDO 引擎将此查询视为返回两个结果集(旧的 mssql 引擎可能只是忽略了整个查询字符串中除了最后一个查询之外的所有查询)。我已经设法通过使用以下命令跳过第一个结果集(临时表)来使其工作

$statement->nextRowset();

然后正常使用$statement->fetch();

【讨论】:

以上是关于将 PDO 与 MS SQL 结合使用“活动结果不包含任何字段”的主要内容,如果未能解决你的问题,请参考以下文章

使用 PDO_DBLIB 连接到 MS SQL 数据库的 PHP 错误

MS SQL SERVER、PHP、PDO、ODBC:用户登录失败

如何将一个字段中的日期与另一字段中的时间结合起来 - MS SQL Server

使用 PDO 在 php 中使用 mac 运行 MS SQL 服务器存储过程

如何在 MS SQL 中将 last_value 与 group by 结合使用?

PHP PDO 使用 SSL 连接到 MS SQLServer Express