How to avoid this PDO exception: Cannot execute queries while other unbuffered queries are active

10,236

Solution 1

You say that you posted a simplified version of the code. Did you change anything else when you posted it here? This error is normally caused when you have multiple queries "open" at the same time. For example, you call fetch(), but you don't call it until it's depleted, and then you try to retrieve a second query.

Judging by your code above, this shouldn't happen because you're using fetchAll(). Normally, the solution to this problem is to call closeCursor() [docs]. You could try calling that after each fetchAll and see if that does anything.

Solution 2

in the loop you are actually fetching the 1st statement again (notice the

$buildings_stmt->fetchAll() call):

$tags_stmt->execute ();
$tags = $buildings_stmt->fetchAll (PDO::FETCH_ASSOC);

what you probably want to do is fetch the $tags_stmt statement?

$tags_stmt->execute ();
$tags = $tags_stmt->fetchAll (PDO::FETCH_ASSOC);
Share:
10,236
vitto
Author by

vitto

I'm a UX/UI developer, located in Italy

Updated on June 19, 2022

Comments

  • vitto
    vitto almost 2 years

    I'd like to print a simple table in my page with 3 columns, building name, tags and architecture style. If I try to retrieve the list of building names and arch. styles there is no problem:

    SELECT buildings.name, arch_styles.style_name
    FROM buildings
    INNER JOIN buildings_arch_styles
    ON buildings.id = buildings_arch_styles.building_id
    INNER JOIN arch_styles
    ON arch_styles.id = buildings_arch_styles.arch_style_id
    LIMIT 0, 10
    

    My problem starts on retreaving the first 5 tags for every building of the query I've just wrote.

    SELECT DISTINCT name
    FROM tags
    INNER JOIN buildings_tags
    ON buildings_tags.tag_id = tags.id
    AND buildings_tags.building_id = 123
    LIMIT 0, 5
    

    The query itself works perfectly, but not where I thought to use it:

    <?php
    
    // pdo connection allready active, i'm using mysql
    $pdo_conn->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, true);
    
    $sql = "SELECT buildings.name, buildings.id, arch_styles.style_name
            FROM buildings
            INNER JOIN buildings_arch_styles
            ON buildings.id = buildings_arch_styles.building_id
            INNER JOIN arch_styles
            ON arch_styles.id = buildings_arch_styles.arch_style_id
            LIMIT 0, 10";
    
    $buildings_stmt = $pdo_conn->prepare ($sql);
    $buildings_stmt->execute ();
    $buildings = $buildings_stmt->fetchAll (PDO::FETCH_ASSOC);
    
    $sql = "SELECT DISTINCT name
            FROM tags
            INNER JOIN buildings_tags
            ON buildings_tags.tag_id = tags.id
            AND buildings_tags.building_id = :building_id
            LIMIT 0, 5";
    $tags_stmt = $pdo_conn->prepare ($sql);
    
    $html = "<table>"; // i'll use it to print my table
    
    foreach ($buildings as $building) {
        $name = $building["name"];
        $style = $building["style_name"];
        $id = $building["id"];
    
        $tags_stmt->bindParam (":building_id", $id, PDO::PARAM_INT);
        $tags_stmt->execute (); // the problem is HERE
        $tags = $tags_stmt->fetchAll (PDO::FETCH_ASSOC);
    
        $html .= "... $name ... $style";
    
        foreach ($tags as $current_tag) {
            $tag = $current_tag["name"];
            $html .= "... $tag ..."; // let's suppose this is an area of the table where I print the first 5 tags per building
        }
    
    }
    $html .= "...</table>";
    print $html;
    

    I'm not experienced on queries, so i though something like this, but it throws the error:

    PHP Fatal error:  Uncaught exception 'PDOException' with message 'SQLSTATE[HY000]: General error: 2014 Cannot execute queries while other unbuffered queries are active.  Consider using PDOStatement::fetchAll().  Alternatively, if your code is only ever going to run against mysql, you may enable query buffering by setting the PDO::MYSQL_ATTR_USE_BUFFERED_QUERY attribute.
    

    What can I do to avoid this? Should I change all and search a different way to get this kind of queries?