Обновление Laravel 8 с помощью запроса DB ::Raw

#php #laravel #upsert #laravel-8

#php #laravel #обновление #laravel-8

Вопрос:

Я хочу использовать встроенную функцию upsert в Laravel 8 для импорта партии продуктов. При использовании пакета https://github.com/staudenmeir/laravel-upsert Я мог бы, например, просто использовать следующее для обновления изображения, если оно не существует в модели БД:

 Product::upsert(
    $values,
    $target,
    [
        'image' => DB::raw("if(`image` is null, values(`image`), `image`)"),
        // TODO: Add the other columns that should be updated.
    ]
);
  

Однако, похоже, это не работает в версии upsert в Laravel 8. Есть идеи о том, как я могу это сделать?

Обновление: код, который я пытаюсь в настоящее время:

 ShopProduct::upsert(
    $productArray,
    ['productcode'],
    [
       'image' => DB::raw("if(`image` is null, values(`image`), `image`)"),
    ]);
  

И ошибка, которую я получаю:

 SQLSTATE[HY000]: General error: 1 near "values": syntax error (SQL: insert into "shop_products" ("created_at", "image", "name", "productcode", "slug", "updated_at") values (2020-11-18 21:52:03, /var/folders/y_/whnvprxj6hx514qmgwj_lb740000gn/T/cf46d09ad8845c9ff742a9045090d252.png, tempora, 6011295759374531, tempora, 2020-11-18 21:52:03), (2020-11-18 21:52:03, /var/folders/y_/whnvprxj6hx514qmgwj_lb740000gn/T/d0842fcf4ea08a4dab9f82e9456fdd36.png, qui, 4024007178334, qui, 2020-11-18 21:52:03) on conflict ("productcode") do update set "image" = if(`image` is null, values(`image`), `image`), "updated_at" = "excluded"."updated_at")
  

Комментарии:

1. Вы уже просмотрели запрос? DB::enableQueryLog(); Product::upsert(...); dd(DB::getQueryLog());

2. @Anticom запрос не будет зарегистрирован из-за ошибки. Я обновил сообщение дополнительной информацией.

3. Вы просматривали документацию по функции , прежде чем пытаться ее использовать? Ничто не указывает на то, что вы можете делать все, что пытаетесь сделать. «Третий и последний аргумент метода — это массив столбцов, которые должны быть обновлены, если соответствующая запись уже существует в базе данных».

4. Да, я сделал @miken32, но поскольку они были реализованы и изменены github.com/staudenmeir/laravel-upsert , Я вроде как надеялся, что это продолжало бы работать. Я думаю, что это нет : (

Ответ №1:

Я использовал эту функцию, чтобы упростить задачу:

 protected function coalesce(array $columnNames):array{
        $columns = [];
        foreach($columnNames as $value){
            $columns["{$value}"] = DB::raw("COALESCE(`{$value}`,values(`{$value}`))");
        }
        return $columns;
    }


ShopProduct::upsert(
    $productArray,
    ['productcode'],
    $this->coalesce(['image]));
  

Coalesce примет либо значение столбца, либо переданное значение, в зависимости от того, равно оно null или нет