我创建了一个过程,其中有两个 select 语句正在运行。
$stmt = $this->_connection->execute("CALL myFunction(:user_id)", [
'user_id' => $userId
]);
但是当我尝试像这样调用 nextRowset() 时
$stmt->nextRowset();
它给了我错误
Call to undefined method Cake\Database\Log\LoggingStatement::nextRowset()
所以,我的问题是如何在 Cakephp 3 中调用 nextRowset()
最佳答案
假设所有核心语句类都扩展 \Cake\Database\Statement\StatementDecorator
在某些时候,您可以访问底层 native \PDOStatement
对象通过 StatementDecorator::getInnerStatement()
,例如:
while ($stmt instanceof StatementDecorator) {
$stmt = $stmt->getInnerStatement();
}
if (!($stmt instanceof \PDOStatement)) {
throw new \RuntimeException('Expected an instance of \PDOStatement');
}
然后您可以使用标准 PDO 语句过程,例如在循环中迭代行集:
do {
$rowset = $stmt->fetchAll(PDO::FETCH_ASSOC);
// ...
} while ($stmt->nextRowset());
正如评论中已经提到的,另一种方法是实现您自己的语句类(并使您的代码期望该具体实现的实例)。为了跨数据库兼容性,您必须实现四个不同的语句,以及四个您需要重新实现 \Cake\Database\Driver::prepare()
的驱动程序。 ,因为这是生成语句实例的地方。
此外,如果您想支持查询日志记录,则必须创建自定义连接类并覆盖 \Cake\Database\Connection::prepare()
或\Cake\Database\Connection::_newLogger()
,因为这是驱动程序生成的语句被包装在 \Cake\Database\Log\LoggingStatement
中的地方如果启用了查询日志记录。
我想说,如果您想要支持的只是内置驱动程序,那么期待 \Cake\Database\Statement\StatementDecorator
实例可能是目前更好的选择,尽管它不是很好。您可能想要suggest adding functionality用于推进多行集语句作为增强功能,但不确定是否会有很多支持。
另请参阅
关于php - 如何在 Cakephp 3 中调用 PDOStatement::nextRowset(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42158753/