问题
I have created a procedure in which i there are two select statements are running.
$stmt = $this->_connection->execute("CALL myFunction(:user_id)", [
'user_id' => $userId
]);
But when i am trying to call the nextRowset() like this
$stmt->nextRowset();
Its giving me error
Call to undefined method Cake\Database\Log\LoggingStatement::nextRowset()
So, My question is how can i call the nextRowset() in Cakephp 3
回答1:
Given that all core statement classes do extend \Cake\Database\Statement\StatementDecorator
at some point, you could get to the underlying native \PDOStatement
object via StatementDecorator::getInnerStatement()
, like:
while ($stmt instanceof StatementDecorator) {
$stmt = $stmt->getInnerStatement();
}
if (!($stmt instanceof \PDOStatement)) {
throw new \RuntimeException('Expected an instance of \PDOStatement');
}
Then you can use standard PDO statement procedures, like iterating over the rowsets in a loop:
do {
$rowset = $stmt->fetchAll(PDO::FETCH_ASSOC);
// ...
} while ($stmt->nextRowset());
As already mentioned in the comments, another way would be to implement your own statement class (and make your code expect an instance of that concrete implementation). For cross DB compatibilty you'd have to implement four different statements though, plus four drivers where you'd re-implement \Cake\Database\Driver::prepare()
, as this is where the statement instances are being generated.
Also in case you want to support query logging, you'd have to create a custom connection class and override \Cake\Database\Connection::prepare()
or \Cake\Database\Connection::_newLogger()
, as this is where the statements generated by driver are being wrapped in \Cake\Database\Log\LoggingStatement
in case query logging is enabled.
I'd say if all you want to support are the built-in drivers, then expecting \Cake\Database\Statement\StatementDecorator
instances is probably the better choice for the time being, even though it's not overly nice. You may want to suggest adding functionality for advancing multi-rowset statements as an enhancement, not sure if there will be much support for it though.
See also
- API > \Cake\Database\Statement\StatementDecorator::getInnerStatement()
- API > \Cake\Database\Driver::prepare()
- API > \Cake\Database\Connection::prepare()
- API > \Cake\Database\Connection::_newLogger()
来源:https://stackoverflow.com/questions/42158753/how-to-call-pdostatementnextrowset-in-cakephp-3