Как установить привязки для необработанного запроса на обновление laravel - PullRequest
0 голосов
/ 19 марта 2020

Я хочу обновить несколько строк одним запросом на обновление. Я могу сделать это без таких привязок:

Product::whereIn('id',[1,2,3])->update([
    'stock' => DB::raw('CASE id WHEN 1 THEN 1000 WHEN 2 THEN 1001 WHEN 3 THEN 1003 END')
]);

Однако я хотел бы использовать привязки данных для оператора CASE. Я попытался:

Product::whereIn('id',[1,2,3])->setBindings([1,1,2,2,3,3])->update([
    'stock' => DB::raw('CASE id WHEN ? THEN ? WHEN ? THEN ? WHEN ? THEN ? END')
]);
Product::whereIn('id',[1,2,3])->update([
    'stock' => DB::raw('CASE id WHEN ? THEN ? WHEN ? THEN ? WHEN ? THEN ? END')
])->setBindings([1,1,2,2,3,3]);

, которые оба вызывают ошибку:

Освещение / База данных / QueryException с сообщением 'SQLSTATE [HY093]: Неверный номер параметра (SQL: update `products` set `stock` = CASE id WHEN 2020-03-19 08:58:16 THEN 1 WHEN 2 THEN 3 WHEN ? THEN ? END, `products`.`updated_at` = ? where `id` in (?, ?, ?) and `products`.`deleted_at` is null)'

Я также пытался:

Product::whereIn('id',[1,2,3])->update([
    'stock' => DB::raw('CASE id WHEN ? THEN ? WHEN ? THEN ? WHEN ? THEN ? END')
         ->setBindings([1,1,2,2,3,3])
]);

, который выдает следующую ошибку:

PHP Ошибка: вызов неопределенный метод Illuminate / Database / Query / Expression :: setBindings () в коде оболочки Shell в строке 1

1 Ответ

0 голосов
/ 19 марта 2020

При более внимательном рассмотрении сообщений об ошибках мне удалось выяснить, что проблема заключалась в том, что привязки по умолчанию для отметки времени в операторе обновления и параметры предложения whereIn перекрывали привязки, которые я установил вручную. Мое решение состояло в том, чтобы переключить предложение whereIn на whereRaw и включить updated_at в операторе обновления:

Product::setBindings([1,1,2,2,3,3,1,2,3])->
    whereRaw('`id` in (?, ?, ?)')->
    update([
        'stock' => DB::raw('case `id` WHEN ? THEN ? WHEN ? THEN ? WHEN ? THEN ? end'),
        'updated_at' => DB::raw('now()'),
    ]);
...