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 部分的第二个标识符值。

另见