如何避免此 PDO 异常:当其他未缓冲的查询处于活动状态时无法执行查询

发布于 2024-08-24 20:37:05 字数 2641 浏览 8 评论 0原文

我想在页面中打印一个简单的表格,其中包含 3 列:建筑物名称标签架构风格。如果我尝试检索建筑物名称arch. styles 没有问题:

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

我的问题始于为我刚刚编写的查询的每个构建检索前 5 个标签。

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

查询本身工作得很好,但不是我想使用它的地方:

<?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;

我在查询方面没有经验,所以我虽然像这样,但它抛出了错误:

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.

我能做些什么来避免这种情况?我应该更改所有内容并以不同的方式搜索来获取此类查询吗?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

只等公子 2024-08-31 20:37:05

你说你发布了代码的简化版本。当您将其发布到此处时,您是否更改了其他内容?当您同时“打开”多个查询时,通常会导致此错误。例如,您调用 fetch(),但直到它耗尽才调用它,然后尝试检索第二个查询。

从上面的代码来看,这种情况不应该发生,因为您正在使用 fetchAll()。通常,解决这个问题的方法是调用 closeCursor() [文档]。您可以尝试在每个 fetchAll 之后调用它,看看是否有任何作用。

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.

独享拥抱 2024-08-31 20:37:05

在循环中,您实际上再次获取第一个语句(注意

$buildings_stmt->fetchAll() 调用):

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

您可能想要做的是获取 $tags_stmt陈述?

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

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);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文