| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192 |
- <?php
- namespace App\Services\common;
- use App\Services\LogService;
- use Illuminate\Support\Facades\DB;
- use App\Traits\ServiceAppAop;
- class BatchUpdateService
- {
- use ServiceAppAop;
- protected $modelClass=BatchUpdate::class;
- public function batchUpdate($tableName = '', $multipleData = array(), $connection = 'mysql')
- {
- if (count($multipleData) == 1) {
- return false;
- }
- if ($tableName ?? false && !empty($multipleData)) {
- // column of fields to update
- $updateColumns = $multipleData[0];
- // table primary key
- $referenceColumn = $updateColumns[0];
- unset($multipleData[0]);
- if (count($multipleData) <= 200) {
- return $this->batchHandle($tableName, $updateColumns, $referenceColumn, $multipleData, $connection);
- } else {
- $chunk_datas = array_chunk($multipleData, 200, true);
- $bool = true;
- foreach ($chunk_datas as $chunk_data) {
- $is_successful = $this->batchHandle($tableName, $updateColumns, $referenceColumn, $chunk_data, $connection);
- $bool = $is_successful && $bool;
- }
- return $bool;
- }
- } else {
- return false;
- }
- }
- private function batchHandle($tableName, $updateColumns, $referenceColumn, $multipleData, $connection = 'mysql')
- {
- $updateSql = "UPDATE " . $tableName . " SET ";
- $sets = [];
- $bindings = [];
- foreach ($updateColumns as $updateColumn) {
- $setSql = ' `' . $updateColumn . '` = CASE';
- foreach ($multipleData as $multipleDatum) {
- $setSql .= ' WHEN ' . $referenceColumn . ' = ? THEN ? ';
- $bindings[] = $multipleDatum[$referenceColumn];
- $bindings[] = $multipleDatum[$updateColumn];
- }
- $setSql .= ' ELSE `' . $updateColumn . "` END";
- $sets[] = $setSql;
- }
- $updateSql .= implode(',', $sets);
- $whereIn = data_get($multipleData, '*.' . $referenceColumn);
- $bindings = array_merge($bindings, $whereIn);
- $whereIn = rtrim(str_repeat('?,', count($whereIn)), ',');
- $updateSql = rtrim($updateSql, ", ") . " WHERE `" . $referenceColumn . "` IN (" . $whereIn . ")";
- try {
- // DB::update
- $bool = DB::connection($connection)->update($updateSql, $bindings);
- app('LogService')->log(__METHOD__, __FUNCTION__, '批量更新' . count($multipleData) . $tableName . $updateSql . json_encode($bindings));
- return $bool;
- } catch (\Exception $e) {
- app('LogService')->log(__METHOD__, __FUNCTION__, '批量更新失败' . count($multipleData) . $tableName . $updateSql . json_encode($bindings) . $e->getMessage() . $e->getTraceAsString());
- return false;
- }
- }
- public function batchUpdateItself($tableName, $column, array $params, $connection = 'mysql')
- {
- $sql = "UPDATE ".$tableName;
- $sql .= " SET ".$column." = CASE ".$column;
- foreach ($params as $key => $value){
- $sql .= " WHEN ".$key." THEN ".$value;
- }
- $sql .= " END WHERE ".$column." IN (".implode(',',array_keys($params)).")";
- try {
- $bool = DB::connection($connection)->update($sql);
- app('LogService')->log(__METHOD__, __FUNCTION__, '批量更新本身' .$sql);
- return $bool;
- }catch (\Exception $e){
- app('LogService')->log(__METHOD__, __FUNCTION__, '批量更新失败 SQL:(' . $sql .") 堆栈:". $e->getMessage() . $e->getTraceAsString());
- return false;
- }
- }
- }
|