CakePHP Query Builder 的 Case 语句导致 `array_combine()` 和类型错误
Case statement with CakePHP Query Builder causes `array_combine()` and type error
我想使用查询生成器在 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)"])])
]);
});
但在这两种情况下,我都收到此错误:
Warning (2): array_combine(): Both parameters should have an equal number of elements [CORE/src/ORM/ResultSet.php, line 528]
Argument 1 passed to Cake\ORM\Entity::__construct() must be of the type array, bool given, called in /var/www/html/vendor/cakephp/cakephp/src/ORM/ResultSet.php on line 602
所以这两个结果都是同一个查询,但它仍然是错误的...
你没有 selecting 任何别名,CASE
表达式将按原样简单地放在 SELECT
子句中,ORM 不喜欢它,因为它尝试将 select 列表键与检索到的行的键相匹配。
这可能需要更好、更有帮助的错误消息,或者 ORM 甚至可能在编译查询时发出警告,不确定。
总之,长话短说,return 一个带有别名的数组,如下所示:
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
部分的第二个标识符值。
另见
我想使用查询生成器在 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)"])])
]);
});
但在这两种情况下,我都收到此错误:
Warning (2): array_combine(): Both parameters should have an equal number of elements [CORE/src/ORM/ResultSet.php, line 528]
Argument 1 passed to Cake\ORM\Entity::__construct() must be of the type array, bool given, called in /var/www/html/vendor/cakephp/cakephp/src/ORM/ResultSet.php on line 602
所以这两个结果都是同一个查询,但它仍然是错误的...
你没有 selecting 任何别名,CASE
表达式将按原样简单地放在 SELECT
子句中,ORM 不喜欢它,因为它尝试将 select 列表键与检索到的行的键相匹配。
这可能需要更好、更有帮助的错误消息,或者 ORM 甚至可能在编译查询时发出警告,不确定。
总之,长话短说,return 一个带有别名的数组,如下所示:
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
部分的第二个标识符值。
另见