我试图在PHP中使用mysqli驱动程序使用多个准备好的语句,并得到臭名昭著的错误:
命令不同步;您现在不能运行此命令
尽管我认为此数据库API严重损害了大脑,但我确实理解了为什么会收到此错误所述的错误,如本问题所述。
在此解决方案中提供了几种解决方案,以及我发现的其他各种解决方案,我所看到的唯一可行的解决方案涉及
$stmt->store_result()
缓冲整个结果集。
但是,我不想缓冲整个结果集-我想丢弃它而不使用(大量)内存来存储它!
所有我想做的事情,就是创建一个准备好的声明,使用bind_param()
和bind_result()
并fetch()
得到一些结果,然后以某种方式接近的结果,这样我可以再次使用statment并运行其他查询到那时。
我已经尝试了几乎所有从语句中使用实际结果对象并显式关闭该对象的方法,并且尝试了调用next_result()
直到它返回null为止。这些解决方案均不能阻止该错误的出现。
因此,如何在a之后关闭结果集并执行其他准备好的语句fetch()
,而又不浪费执行的语句而不必重新解析查询呢?
$q = $dbc->prepare("SELECT id, typename, storageclass, tablename FROM _dbtype WHERE typename=?");
$q->bind_param("s", $typeName);
$q->bind_result($id,$typeName,$storageClass,$tableName);
$q->execute();
$q->fetch(); // ie. only once
... <something that does not destroy $q> ...
$q2 = $dbc->prepare("SELECT id, name FROM _storagetype");
请参见mysqli_stmt :: free_result()
(和http://dev.mysql.com/doc/refman/5.7/en/mysql-stmt-free-result.html ),以获得“如果该语句有游标, ,mysql_stmt_free_result()将其关闭。”)
<?php
mysqli_report(MYSQLI_REPORT_STRICT|MYSQLI_REPORT_ALL);
$mysqli = new mysqli('localhost', 'localonly', 'localonly', 'test');
if ($mysqli->connect_errno) {
trigger_error( sprintf('mysqli connect error (%d) %s', $mysqli->connect_errno, $mysqli->connect_error), E_USER_ERROR);
die;
}
$mysqli->query('CREATE TEMPORARY TABLE sofoo ( id int auto_increment, primary key(id))');
$mysqli->query('INSERT INTO sofoo VALUES (),(),(),(),(),()');
$stmtA = $mysqli->prepare('SELECT id FROM sofoo WHERE id>1');
$stmtB = $mysqli->prepare('SELECT id FROM sofoo WHERE id<10 ORDER BY id DESC');
$stmtA->execute();
$stmtA->bind_result($id);
$stmtA->fetch(); echo $id, PHP_EOL;
$stmtA->free_result(); // without this the script ends with "Fatal error: Uncaught mysqli_sql_exception: Commands out of sync;"
$stmtB->execute();
$stmtB->bind_result($id);
$stmtB->fetch(); echo $id, PHP_EOL;
如果有多个结果集(即,如果必须使用next_result()
),则必须分别调用free_result()
每个结果集。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句