我希望仅针对某些请求进行无缓冲查询。
在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实例设置为无缓冲?
答案 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不实现语句级属性设置。
来源:
这是您的错误消息:
https://github.com/php/php-src/blob/master/ext/pdo/pdo_stmt.c#L1630
pdo_raise_impl_error(stmt->dbh, stmt, "IM001", "This driver doesn't support setting attributes");
上面的条件在上面的stmt->methods->set_attribute
上进行了检查。
stmt->methods
已在上面定义,并且类型在以下位置声明:
struct pdo_stmt_methods
set_attribute
参数是第十个结构项。
这是MySQL PDO实现。语句方法在这里定义:
NULL, /* set_attr */
这表明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);