使用PDO对一个请求执行无缓冲查询

时间:2014-01-09 15:21:57

标签: php pdo request unbuffered

我希望仅针对某些请求进行无缓冲查询。

在mysql中我这样做:

$req = mysql_unbuffered_query('SELECT * FROM forum_topics
ORDER BY (topic_id/topic_stick) DESC, topic_last_post DESC');
while($data = mysql_fetch_assoc($req)) {
   // display results...
}

我查看了php doc,并根据它在pdo中我们必须以这种方式进行无缓冲的查询:

$pdo = new PDO("mysql:host=localhost;dbname=world", 'my_user', 'my_pass');
$pdo->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false);

$uresult = $pdo->query("SELECT Name FROM City");

if ($uresult) {
   while ($row = $uresult->fetch(PDO::FETCH_ASSOC)) {
       echo $row['Name'] . PHP_EOL;
   }
}

但是,是否可以仅针对“forum_topics”表结果进行无缓冲,而无需将所有pdo实例设置为无缓冲?

5 个答案:

答案 0 :(得分:8)

Re,这不起作用,我在使用你的方法时遇到错误:

SQLSTATE [IM001]:驱动程序不支持此功能:此驱动程序不支持设置属性

怎么了?

编辑:我在php.net doc上找到了解决方案。

如果您使用此:

$sth->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false);

它不起作用。

但是如果你在prepare()中的数组中设置它,它就可以正常工作。

$sth = $pdo->prepare('SELECT * FROM my_table',
array(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => false));

我希望这会帮助那些没有找到解决方案的人。

答案 1 :(得分:2)

如果您使用预准备语句(您可以使用它们进行简单选择),请执行以下操作:

$uresult = $pdo->prepare("SELECT Name FROM City");

然后你可以在uresult上设置属性:

$uresult->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false);

然后执行预准备语句:

$uresult->execute();
if ($uresult) {
   while ($row = $uresult->fetch(PDO::FETCH_ASSOC)) {
       echo $row['Name'] . PHP_EOL;
   }
}

然后unbuffered属性应仅应用于您的语句,而不是整个pdo对象

答案 2 :(得分:1)

MySQL不实现语句级属性设置。

来源:

这是您的错误消息:

上面的条件在上面的stmt->methods->set_attribute上进行了检查。

stmt->methods已在上面定义,并且类型在以下位置声明:

set_attribute参数是第十个结构项。

这是MySQL PDO实现。语句方法在这里定义:

这表明MySQL PDO模块确实实现了该功能。

讨论:

我已经审查了其他扩展。而且只有Firebird PDO数据库模块支持该功能。

答案 3 :(得分:0)

作为解决方法,如果我的查询是SELECT,则不调用fetchAll函数。

                $query = 'SELECT ...... ';
                $arr = explode(' ', $query);
                $query_type = strtolower($arr[0]);
                if ($query_type == 'select') {
                    $query_response = $query_prepare->fetchAll(PDO::FETCH_ASSOC);
                } else {
                    $query_response = '';
                }

此外,当您在查询开始时不小心加空格时,必须处理该异常。 希望这会有所帮助。

答案 4 :(得分:0)

这里的答案都是试图在语句上使用MYSQL_ATTR_USE_BUFFERED_QUERY 。并且MYSQL_ATTR_USE_BUFFERED_QUERY仅在整个连接上都有效,因为您似乎已经感到困惑。

MYSQL_ATTR_USE_BUFFERED_QUERY也仅在使用mysqlnd库时才有效-如果您使用的是PHP 7或更高版本,这是个好机会。

您最初将连接设置为无缓冲的方法是正确的,并且只有实际上个功能方法。

$pdo->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false);

但是是否有可能仅针对“ forum_topics”表结果进行无缓冲设置,而无需将所有pdo实例设置为无缓冲?

并非所有 instances 都设置为非缓冲的,只有该连接的那个“ instance”。您可以直接在ala上立即打开缓冲:

$pdo->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, true);

问题在于,在非缓冲模式下,每个连接只能迭代一个查询,因此只有从第一组中检索到所有数据后才能运行第二个查询。

通常,您只想对非常大的数据集使用无缓冲查询。我建议为需要仅运行 的无缓冲查询使用第二个PDO连接到数据库,当您需要运行无缓冲查询时,又名:

$pdo2 = new PDO("mysql:host=localhost;dbname=world", 'my_user', 'my_pass');
$pdo2->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, true);