无法判断是否执行了 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) {
// ...
}
}
初始尝试:
- getting
$statement->errorCode
为 null,不是 0
- 获取
$statement->_hasExecuted
为空
- getting
$query->executed
throws Notice Error: Undefined 属性: Cake\ORM\Query::$executed (虽然看起来好像在那里)
- 有趣的是,在上面的调试输出中,
$statement->_hasExecuted
是 false
而 $query->executed
是 true
我的思考过程是这样的:我调用 $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 端没有错误,当然除非您已将连接的错误模式更改为 silent 或 warning 模式,即当您 could/would 使用 errorCode()
时,否则将不可用,因为异常会阻止语句首先可用。
没有 DBMS 错误是否意味着您的查询完全按照预期执行,这可能是一个不同的问题,取决于查询的具体内容,并且是您需要通过以下方式弄清楚的情况案例基础。实际验证的唯一选择是查看受影响的行数,and/or 之后查询数据库。
我有一个执行查询的自定义模型方法,我需要它 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) {
// ...
}
}
初始尝试:
- getting
$statement->errorCode
为 null,不是 0 - 获取
$statement->_hasExecuted
为空 - getting
$query->executed
throws Notice Error: Undefined 属性: Cake\ORM\Query::$executed (虽然看起来好像在那里) - 有趣的是,在上面的调试输出中,
$statement->_hasExecuted
是false
而$query->executed
是true
我的思考过程是这样的:我调用 $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 端没有错误,当然除非您已将连接的错误模式更改为 silent 或 warning 模式,即当您 could/would 使用 errorCode()
时,否则将不可用,因为异常会阻止语句首先可用。
没有 DBMS 错误是否意味着您的查询完全按照预期执行,这可能是一个不同的问题,取决于查询的具体内容,并且是您需要通过以下方式弄清楚的情况案例基础。实际验证的唯一选择是查看受影响的行数,and/or 之后查询数据库。