php - CakePHP Query Builder 的 case 语句导致 `array_combine()` 和类型错误
问题描述
我想使用查询生成器在 CakePHP 中编写以下查询:
SELECT
(CASE
WHEN `ai` = 1 THEN CONCAT_WS(" ", `name`, " (AI)") ELSE `name`
END) AS `name`
FROM `drivers`;
我尝试了几种方法,但似乎总是失败。首先,我尝试了这个:
return $query->select(function(Query $query) {
return $query->newExpr()->addCase([
$query->newExpr()->add(['ai' => 1])
], [
$query->newExpr()->add(['name' => 'CONCAT_WS(" ", `name`, " (AI)")'])
]);
});
我试过这个:
return $query->select(function(Query $query) {
return $query->newExpr()->addCase([
$query->newExpr()->add(['ai' => 1])
], [
$query->newExpr()->add(['name' => $query->func()->concat([" ", 'name', " (AI)"])])
]);
});
但在这两种情况下,我都会收到此错误:
警告 (2): array_combine(): 两个参数应该有相同数量的元素 [CORE/src/ORM/ResultSet.php, line 528]
传递给 Cake\ORM\Entity::__construct() 的参数 1 必须是数组类型,bool 给定,在第 602 行的 /var/www/html/vendor/cakephp/cakephp/src/ORM/ResultSet.php 中调用
所以这两个结果都是相同的查询,但它仍然是错误的......
解决方案
您没有选择任何别名,CASE
表达式将按原样放在SELECT
子句中,这是 ORM 不喜欢的,因为它尝试将选择列表键与检索到的行的键匹配。
这可能需要更好、更有帮助的错误消息,或者 ORM 甚至可能在编译查询时发出警告,不确定。
无论如何,长话短说,返回一个带有别名的数组,如下所示:
return $query->select(function(Query $query) {
$case = $query->newExpr()->addCase(
[
// WHEN
$query->newExpr()->add(['ai' => 1])
],
[
// THEN
$query->func()->concat([' ', $query->identifier('name'), ' (AI)']),
// ELSE
$query->identifier('name')
]
);
return [
'name' => $case,
];
});
另请注意,您需要直接传入CONCAT()
函数表达式,不要将其包装在另一个将结果分配给某些东西的表达式中,那将不起作用。此外,您需要确保标识符是这样传递的,目前您的name
值将绑定为带引号的字符串文字,并且您还需要该ELSE
部分的第二个标识符值。
也可以看看
推荐阅读
- opencv - OpenCV phase() 函数在这种极端情况下是否正常工作?
- perl - 使用 Perl 我想使用 SFTP 过滤名称与特定模式匹配的文件
- tomcat - 为什么 Intellij 在使用 tomcat 运行配置时会复制并覆盖我过滤的 web.xml?
- ionic3 - Ionic 3:文件传输下载,文件不在目录中但没有错误代码
- java - 如何使用 Google Truth(单元测试)使用其中一个属性来比较两个元素
- javascript - 如何将 ruby - Rspec 转换为 js 测试 - opal gem
- php - PHP在mysqli执行后在while循环中跳过打印语句,但在循环后显示打印
- c# - 多次刷新后从服务器获取服务器错误 503
- django - 返回带有验证错误的单个响应,包括唯一的用户名约束
- ruby-on-rails - 检查 ActiveRecord 数组中的单元格是否已更改