Laravel 批量更新

176 阅读1分钟
/**
     * 批量更新
     * @param array $multipleData
     * @return bool
     */
    public function updateBatch($multipleData = [], $whereNum = 1)
    {
        try {
            if (empty($multipleData)) {
                throw new \Exception("数据不能为空");
            }
            $tableName = DB::getTablePrefix() . $this->getTable(); // 表名
            $firstRow = current($multipleData);

            $updateColumn = array_keys($firstRow);

            for ($i = 1; $i <= $whereNum; $i++) {
                // 默认以id为条件更新,如果没有ID则以第一个字段为条件
                $referenceColumns[] = current($updateColumn);
                unset($updateColumn[0]);
            }

            isset($firstRow['id']) ? $referenceColumn[] = 'id' : '';

            // 拼接sql语句
            $updateSql = "UPDATE " . $tableName . " SET ";
            $sets = [];
            $bindings = [];
            foreach ($updateColumn as $uColumn) {
                $setSql = "`" . $uColumn . "` = CASE ";
                foreach ($multipleData as $data) {
                    $setSql .= "WHEN ";
                    foreach ($referenceColumns as $referenceColumn) {
                        $setSql .= '`' . $referenceColumn . "` = ? AND ";
                        $bindings[] = $data[$referenceColumn];
                    }
                    $setSql = substr($setSql, 0, strrpos($setSql, "AND "));
                    $setSql .= " THEN ? ";
                    $bindings[] = $data[$uColumn];
                }
                $setSql .= "ELSE `" . $uColumn . "` END ";
                $sets[] = $setSql;
            }
            $updateSql .= implode(', ', $sets);
            $whereIn = collect($multipleData)->pluck($referenceColumn)->values()->all();
            $bindings = array_merge($bindings, $whereIn);
            $whereIn = rtrim(str_repeat('?,', count($whereIn)), ',');
            $updateSql = rtrim($updateSql, ", ") . " WHERE `" . $referenceColumn . "` IN (" . $whereIn . ")";

            // 传入预处理sql语句和对应绑定数据
            return DB::update($updateSql, $bindings);
        } catch (\Exception $e) {
            return false;
        }
    }