我有一个执行查询的自定义模型方法,我需要它根据成功与否返回true或false。没有明确的答案,所以我想自己弄清楚它是如何工作的。这是我的代码:
// build and execute the query
$query = $myTable->query();
$query->insert(array_keys(reset($data)));
$query->clause('values')->setValues($data);
$query->epilog('ON DUPLICATE KEY UPDATE `price`=VALUES(`price`)');
$statement = $query->execute();
调试上面的代码是这样的:
'$statement' => object(Cake\Database\Statement\MysqlStatement) {
[protected] _statement => object(PDOStatement) {
queryString => 'INSERT INTO `table` (`id`, `value_id`, `price`) VALUES (...) ON DUPLICATE KEY UPDATE `price`=VALUES(`price`)'
}
[protected] _driver => object(Cake\Database\Driver\Mysql) {
'connected' => true
}
[protected] _hasExecuted => false
[protected] _bufferResults => true
},
'$query' => object(Cake\ORM\Query) {
'(help)' => 'This is a Query object, to get the results execute or iterate it.',
'sql' => 'INSERT INTO `table` (`id`, `value_id`, `price`) VALUES (...) ON DUPLICATE KEY UPDATE `price`=VALUES(`price`)',
'params' => [
// ...
],
'defaultTypes' => [
// ...
],
'decorators' => (int) 0,
'executed' => true,
'hydrate' => true,
'buffered' => true,
'formatters' => (int) 0,
'mapReducers' => (int) 0,
'contain' => [],
'matching' => [],
'extraOptions' => [],
'repository' => object(App\Model\Table\SomeTable) {
// ...
}
}
初始尝试:
$statement->errorCode
为null,而不是0 $statement->_hasExecuted
为空$query->executed
会引发通知错误:未定义的属性:Cake \ ORM \ Query :: $ exected (尽管好像在那里)$statement->_hasExecuted
是false
,而$query->executed
是true
我的思考过程是这样的:我叫$query->execute()
,其中的calls $this->_connection->run($this)
,creates and executes a \Cake\Database\StatementInterface
。就我而言,它是MysqlStatement
extended from a PDOStatement
。在execute()
call内部,它显式sets _hasExecuted
to true;然后调用$this->_statement->execute()
,being an implementation of that same Cake\Database\StatementInterface::execute()
显然会运行该确切的execute方法,包括_hasExecuted
= true
部分。
据我了解,该语句最终返回并显示在上面的调试中。并且将_hasExecuted
设置为false
。那它没有执行吗?
这使我感到困惑,我需要您的帮助。如何确定查询已成功执行?我找不到受影响的行数,因为它可能是0。我在CakePHP Support Slack上询问,建议检查调试面板或稍后重新查询表以确认条目已创建,但是我需要此作为自动化的代码测试,因此这些都不起作用。
答案 0 :(得分:1)
MySqlStatement::excute()
方法不会更改_hasExecuted
标志,也不会调用父方法。这可能是一个疏忽,也可能是设计性的,不更改标志,例如允许多次迭代该语句(这涉及再次发出查询),您可以在GitHub上打开一个问题进行澄清,或者尝试通过Slack召唤ORM大师又名Lorenzo。
Query::$executed
属性确实不存在,您正在查看的custom debug information不能反映对象结构,executed
键基于内部_iterator
属性。
如果执行查询没有触发异常,则说明它已成功运行,即在DBMS端没有错误,除非您当然已将连接的错误模式更改为 silent 或< em> warning 模式,那是您可以/将要使用errorCode()
的时候,否则该模式将不可用,因为异常会阻止该语句首先出现。
是否没有DBMS错误意味着您的查询完全按照预期的方式执行了,可能是一个不同的问题,并且取决于查询的确切执行方式,因此您需要根据具体情况进行确定。进行实际验证的唯一选择是查看受影响的行数,和/或之后再查询数据库。
答案 1 :(得分:0)
query()->execute()->execute()
呢?它至少返回一个布尔值。