Оператор case с Cake PHP Query Builder вызывает `array_combine ()` и ошибку типа - PullRequest
0 голосов
/ 20 апреля 2020

Я хочу написать следующий запрос в Cake PHP с помощью Query Builder:

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, строка 528]

Аргумент 1 передан в Cake \ ORM \ Entity: : __ construct () должен иметь тип массива, заданный bool, вызываемый в / var / www/html/vendor/cakephp/cakephp/src/ORM/ResultSet.php в строке 602

Таким образом, оба эти запроса приводят к одному и тому же запросу, но это все равно неправильно .. .

1 Ответ

1 голос
/ 20 апреля 2020

Вы не выбираете псевдонимы, выражение 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.

См. также

...