php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #50462 mysqli_more_results does not play well with mysqli_multi_query()
Submitted: 2009-12-12 21:41 UTC Modified: 2009-12-13 19:47 UTC
From: pcdinh at gmail dot com Assigned:
Status: Not a bug Package: MySQLi related
PHP Version: 5.3.1 OS: Windows XP
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: pcdinh at gmail dot com
New email:
PHP Version: OS:

 

 [2009-12-12 21:41 UTC] pcdinh at gmail dot com
Description:
------------
mysqli_more_results() will always return false after 
mysqli_multi_query() for both SELECT and non SELECT queries

Therefore I can not use the loop while (mysqli_more_results()) in 
combination with mysqli_next_result() to iterate through result sets 
produced by SELECT queries

mysqli_multi_query($conn, $query);

while (mysqli_more_results($conn))
{
    mysqli_next_result($query);

    /* store first result set */
    if ($result = mysqli_store_result($conn)) {
 
    }
}

Code example in http://php.net/manual/en/mysqli.multi-query.php is 
outdated because it causes E_STRICT in PHP 5.3.1. It requires 
mysqli_more_results() to be called before mysqli_next_result()

There is a workaround

if (mysqli_multi_query($link, $query)) {
    do {
        /* store first result set */
        if ($result = mysqli_store_result($link)) {
            while ($row = mysqli_fetch_row($result)) {
                printf("%s\n", $row[0]);
            }
            mysqli_free_result($result);
        }

        // print divider => will never work
        if (mysqli_more_results($link)) {
            printf("-----------------\n");
        }
    } while (mysqli_more_results($link) && mysqli_next_result($link));
}

but mysqli_more_results() seems to do nothing related to result sets 
here


Reproduce code:
---------------
<?php
$link = mysqli_connect("localhost", "root", "123456", "test");

/* check connection */
if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

$query  = "SELECT 1";

/* execute multi query */
if (mysqli_multi_query($link, $query)) {
    var_dump(mysqli_more_results($link));      
}

/* close connection */
mysqli_close($link);
?>

Expected result:
----------------
bool(true)

Actual result:
--------------
bool(false)

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2009-12-12 21:54 UTC] pcdinh at gmail dot com
Hi,

I found that mysqli_more_results() return true when there is more than 
1 query

<?php
$link = mysqli_connect("localhost", "root", "123456", "test");

/* check connection */
if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

$query  = "SELECT 1;";
$query  .= "SELECT 1;"; // second query

/* execute multi query */
if (mysqli_multi_query($link, $query)) {
    var_dump(mysqli_more_results($link)); 
}

?>

bool(true)

However, this behavior is totally confused
 [2009-12-12 22:19 UTC] jani@php.net
Exactly what is confusing here? Your first script does single query -> there are no more results than the one. So why would mysqli_more_results() return true since there are no more results..?
 [2009-12-13 05:44 UTC] pcdinh at gmail dot com
The problem is mysqli_more_results($conn) needs to be called first to 
check if there is at least one result returned.

The code below is valid if I make a single query that returns multiple 
result set 

mysqli_multi_query($conn, $query);

while (mysqli_more_results($conn))
{
    mysqli_next_result($query);

    /* store first result set */
    if ($result = mysqli_store_result($conn)) {
 
    }
}

When I use mysqli_multi_query() I may not know how many queries are 
there in $query. Therefore I would like to use mysqli_more_results() 
to check if I can loop through the result sets. It is the same as in 
array iteration

Single element: array(1)    => using for: yes
2 elements:     array(1, 2) => using for: yes

But when it comes to mysqli_multi_query()

Single element: array(1)    => using while: no
2 elements:     array(1, 2) => using while: yes

Because mysqli_multi_query() deals with multiple result sets, it is 
expected to have unified iteration interface for both single result 
set and multiple result sets.

Also the behavior is defined in PHP Manual that 

"Indicates if one or more result sets are available from a previous 
call to mysqli_multi_query()."

It means that mysqli_more_results($conn) must return true in my case

mysqli_multi_query($conn, $query);

while (mysqli_more_results($conn))
{

}

because in fact I do not know if there is any result returned at all 
after calling mysqli_multi_query(). So while 
(mysqli_more_results($conn)) is a good way to do if any.
 [2009-12-13 19:47 UTC] johannes@php.net
Thank you for taking the time to write to us, but this is not
a bug. Please double-check the documentation available at
http://www.php.net/manual/ and the instructions on how to report
a bug at http://bugs.php.net/how-to-report.php

Your code is wrong. There will always be one result set which will be active. mysqli_more_results() will tell you whether there is yet another result set but you're on the last (and only) result set so there's no other.
 [2013-01-24 17:25 UTC] freeman3 at centrum dot cz
Perhaps this should be written more clearly in the docs. I though also it works differently.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Tue Dec 03 08:01:28 2024 UTC