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

Can't tell if a Cake\ORM\Query was executed

我有一个执行查询的自定义模型方法,我需要它 return 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) {
        // ...
    }

}

初始尝试:

我的思考过程是这样的:我调用 $query->execute(), which inside of it calls $this->_connection->run($this), which creates and executes a \Cake\Database\StatementInterface. In my case it's a MysqlStatement extended from a PDOStatement. Inside the execute() call, it explicitly sets _hasExecuted to true; then it calls $this->_statement->execute(), which, being an implementation of that same Cake\Database\StatementInterface::execute(),显然运行了那个确切的执行方法,包括 _hasExecuted=true 部分。

据我了解,这是最终 returned 并在上面的调试中显示的语句。并将 _hasExecuted 设置为 false。那么是不是没有执行呢?

这让我很困惑,我需要你的帮助。我如何确定查询已成功执行?我无法查找受影响的行数,因为它可能为 0。我在 CakePHP Support Slack 上询问并被建议检查调试面板或稍后重新查询 table 以确认条目已创建,但我自动化代码测试需要这个,所以 none 可以工作。

query()->execute()->execute()呢?它至少 returns 一个布尔值。

MySqlStatement::excute()方法不改变_hasExecuted标志,也不调用父方法。这可能是一个疏忽,也可能是设计使然,例如不更改标志允许多次迭代语句(这涉及再次发出查询),您可以在 GitHub 打开一个问题进行澄清,或尝试通过 Slack 召唤 ORM 大师 aka Lorenzo。

Query::$executed 属性 确实不存在,你看到的是 custom debug information 不反映对象结构, executed密钥基于内部 _iterator 属性.

如果执行查询没有触发异常,则它 运行 成功,即 DBMS 端没有错误,当然除非您已将连接的错误模式更改为 silentwarning 模式,即当您 could/would 使用 errorCode() 时,否则将不可用,因为异常会阻止语句首先可用。

没有 DBMS 错误是否意味着您的查询完全按照预期执行,这可能是一个不同的问题,取决于查询的具体内容,并且是您需要通过以下方式弄清楚的情况案例基础。实际验证的唯一选择是查看受影响的行数,and/or 之后查询数据库。