无法判断是否执行Cake \ ORM \ Query

时间:2019-08-07 11:22:28

标签: cakephp cakephp-3.0

我有一个执行查询的自定义模型方法,我需要它根据成功与否返回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->_hasExecutedfalse,而$query->executedtrue

我的思考过程是这样的:我叫$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上询问,建议检查调试面板或稍后重新查询表以确认条目已创建,但是我需要此作为自动化的代码测试,因此这些都不起作用。

2 个答案:

答案 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()呢?它至少返回一个布尔值。