“使用PDO和MS SQL,活动结果不包含任何字段”

时间:2013-05-24 13:16:35

标签: php sql-server pdo

我正在将一些旧的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);

这似乎解决了这个错误,但是这个版本的查询非常低效,因为它似乎在另一个查询中为每个字段比较运行temptable查询。

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

在使用mssql的旧页面上工作正常。

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

6 个答案:

答案 0 :(得分:45)

如果您使用的是存储过程,请使用

SET NOCOUNT ON 

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

Microsoft Documentation

答案 1 :(得分:13)

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

$statement->nextRowset();

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

答案 2 :(得分:5)

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

  1. 您可以使用SET NOCOUNT ON和您修改sproc 想要这样做
  2. 您确定需要转到下一个行集 $statement->nextRowset();
  3. 在我的情况下,我使用泛型方法从多个sprocs中提取数据,我可能会或可能不会遇到此问题,需要在递增行集之前进行检查。

    我使用了以下内容:

    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 :(得分:4)

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

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

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

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

此后不再出现错误。

答案 4 :(得分:1)

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

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

答案 5 :(得分:0)

我在此版本中使用Laravel5,您应该执行

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

效果很好。