9

I'm in the process of converting a PHP application from running in a Windows environment to a Linux based environment.

It utilises PDO to run Stored Procedures against a Microsoft SQL Server database.

So, I've installed and configured PHP 5.6.22, Apache, freetds and pdo dblib to facilitate the application.

Most stored procedure executions are working perfectly. Except ones that return multiple rowsets.

When I call $pdo->nextRowset(), I get this fatal error:

SQLSTATE[HY000]: General error: PDO_DBLIB: dbresults() returned FAIL

The only reference I can find to this was a bug reported in PHP 5.6.9 that was fixed.

However, I am getting the same issue in PHP 5.6.22.

Does anyone have any ideas why this is happening and how I can resolve it?

Jamesking56
  • 3,683
  • 5
  • 30
  • 61
  • Can you return a more detailed error than fail by tweaking whatever that setting in `php.ini` for error verbosity is (sorry, haven't touched PHP in years or I'd be more specific). If we can get the actual FreeTDS error to bubble to the surface, that'd be much easier to diagnose, since you're likely swapping out the SQL Server driver on Windows for FreeTDS on Linux. – FlipperPA Jun 25 '16 at 23:23
  • PHP is on highest verbosity and only shows the error message in my question. – Jamesking56 Jun 27 '16 at 08:07
  • Just checking, did you run the procedure through a fetchall? – Ctc Jun 27 '16 at 08:12
  • @Ctc I just use `fetch()` for each rowset since it only returns 1 row per rowset. – Jamesking56 Jun 27 '16 at 08:14
  • @Jamesking56 could you please post the code which executes and fetches the results. – gofr1 Jun 28 '16 at 14:08
  • Are you sure that returning multiple rowsets is necessary? Maybe it could be much simpler to split code returning multiple rowsets into smaller pieces and call them separately. – Aleksey Ratnikov Jun 29 '16 at 16:49
  • @Jamesking56 did you try my answer ? I resolved with that "work-around" – Simone Pessotto Jul 04 '16 at 16:29

2 Answers2

4

Are you fetching data with PDO::fetch or PDO::fetchAll ? Because if you use the "fetch" method and don't reach the end of the rows PDO::nextRowset() will fail (I don't know why, it just happened to me).

So, for me works to force to scan all rows until PDO::fetch returns false, then PDO::nextRowset() will execute normally.

It means that if you have only one row in a rowset you must call PDO::fetch at least two time (1 for retrieve data and 1 to return false) and then pass to next rowset.

Simone Pessotto
  • 1,561
  • 1
  • 15
  • 19
1

I had same problem with PDO::nextRowset(), as it returns true even there is no more rowsets available, therefore when calling fetchAll(), it raises exception HY000.

you can follow a simple trick by checking number of columns with method PDO::columnCount() before fetching rowset. If it is non-zero, you have a valid rowset, and thus you could call PDO::fetchAll().

Even if PDO::nextRowset() reports true, columnCount() will report number of columns before moving to next rowset.

while ($pdo->columnCount()) {
    $data[] = $pdo->fetchAll(PDO::FETCH_ASSOC); //or, $pdo->fetchAll() 
    $pdo->nextRowset();
}

Also, it is recommended to make all PDO operations within the try block, otherwise you may get unhandled exceptions.

RU Ahmed
  • 558
  • 4
  • 23