INSERT IGNORE using Laravel's Fluent

前端 未结 10 1276
执笔经年
执笔经年 2020-12-11 02:12

Is there a quick way to modify a SQL query generated by Laravel\'s Fluent to have an INSERT IGNORE instead of the usual INSERT?

I\'m trying

10条回答
  •  囚心锁ツ
    2020-12-11 02:41

    Updated answer for Laravel Eloquent in 2018

    This also handles multiple simultaneous inserts (instead of one record at a time).

    Warning: Eric's comment below is probably correct. This code worked for my past project, but before using this code again, I'd take a closer look at it and add test cases and adjust the function until it always works as intended. It might be as simple as moving the TODO line down outside the if braces.

    Either put this in your model's class or in a BaseModel class that your model extends:

    /**
     * @see https://stackoverflow.com/a/25472319/470749
     * 
     * @param array $arrayOfArrays
     * @return bool
     */
    public static function insertIgnore($arrayOfArrays) {
        $static = new static();
        $table = with(new static)->getTable(); //https://github.com/laravel/framework/issues/1436#issuecomment-28985630
        $questionMarks = '';
        $values = [];
        foreach ($arrayOfArrays as $k => $array) {
            if ($static->timestamps) {
                $now = \Carbon\Carbon::now();
                $arrayOfArrays[$k]['created_at'] = $now;
                $arrayOfArrays[$k]['updated_at'] = $now;
                if ($k > 0) {
                    $questionMarks .= ',';
                }
                $questionMarks .= '(?' . str_repeat(',?', count($array) - 1) . ')';
                $values = array_merge($values, array_values($array));//TODO
            }
        }
        $query = 'INSERT IGNORE INTO ' . $table . ' (' . implode(',', array_keys($array)) . ') VALUES ' . $questionMarks;
        return DB::insert($query, $values);
    }
    

    Use like this:

    Shop::insertIgnore([['name' => 'myShop'], ['name' => 'otherShop']]);

提交回复
热议问题