今天實現(xiàn)laravel 批量更新數(shù)據(jù),發(fā)現(xiàn)沒有這個功能,在社區(qū)也沒搜到,所以網上找了一份
public function updateBatch($tableName,$multipleData = [])
{
try {
if (empty($multipleData)) {
throw new \Exception("數(shù)據(jù)不能為空");
}
$firstRow = current($multipleData);
$updateColumn = array_keys($firstRow);
// 默認以id為條件更新,如果沒有ID則以第一個字段為條件
$referenceColumn = isset($firstRow['id']) ? 'id' : current($updateColumn);
unset($updateColumn[0]);
// 拼接sql語句
$updateSql = "UPDATE " . $tableName . " SET ";
$sets = [];
$bindings = [];
foreach ($updateColumn as $uColumn) {
$setSql = "`" . $uColumn . "` = CASE ";
foreach ($multipleData as $data) {
$setSql .= "WHEN `" . $referenceColumn . "` = ? THEN ? ";
$bindings[] = $data[$referenceColumn];
$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語句和對應綁定數(shù)據(jù)
return DB::update($updateSql, $bindings);
} catch (\Exception $e) {
return false;
}
}
$update = array(
array('id'=>1,'name'=>'aa','area'=>'bb'),
array('id'=>2,'name'=>'cc','area'=>'dd'),
array('id'=>3,'name'=>'ee','area'=>'ff')
);
try{
$this->updateBatch($this->Create->getTable(),$update);
echo 'update success';
}catch (\Exception $e){
echo $e->getMessage();
}
DB::table 和 Db::table有啥區(qū)別?
upsert 不就可以批量更新
upsert方法將插入不存在的記錄,并用您指定的新值更新已存在的記錄。該方法的第一個參數(shù)由要插入或更新的值組成。而第二個參數(shù)列出列唯一標識關聯(lián)表中記錄的方法。方法'的第三個也是最后一個參數(shù)是一個列數(shù)組,如果數(shù)據(jù)庫中已存在匹配記錄,則應更新該數(shù)組 手冊中有 寫法參考https://learnku.com/articles/59138
$cases = [
['id' => 1, 'name' => 'John', 'email' => 'john@example.com'],
['id' => 2, 'name' => 'Alice', 'email' => 'alice@example.com'],
['id' => 3, 'name' => 'Bob', 'email' => 'bob@example.com'],
];
$uniqueKey = 'id';
User::upsert($cases, $uniqueKey, ['name', 'email']);
這樣就能批量更新
哈哈,我也有個,功能更齊全點,可以用表達式、分隔
if (!function_exists('laravel_batch_update')) {
/**
* laravel數(shù)據(jù)庫單表批量更新,適用于laravel
* @param string $table
* @param array $list_data
* @param int $chunk_size
* @return int
* @author mosquito <zwj1206_hi@163.com> 2020-10-21
*/
function laravel_batch_update(string $table, array $list_data, int $chunk_size = 200)
{
if (count($list_data) < 1) {
throw new \Exception('更新數(shù)量不能小于1');
}
if ($chunk_size < 1) {
throw new \Exception('分切數(shù)量不能小于1');
}
$chunk_list = array_chunk($list_data, $chunk_size);
$count = 0;
foreach ($chunk_list as $list_item) {
$first_row = current($list_item);
$update_col = array_keys($first_row);
// 默認以id為條件更新,如果沒有ID則以第一個字段為條件
$reference_col = isset($first_row['id']) ? 'id' : current($update_col);
unset($update_col[0]);
// 拼接sql語句
$update_sql = 'UPDATE ' . $table . ' SET ';
$sets = [];
$bindings = [];
foreach ($update_col as $u_col) {
$set_sql = '`' . $u_col . '` = CASE ';
foreach ($list_item as $item) {
$set_sql .= 'WHEN `' . $reference_col . '` = ? THEN ';
$bindings[] = $item[$reference_col];
if ($item[$u_col] instanceof \Illuminate\Database\Query\Expression) {
$set_sql .= $item[$u_col]->getValue() . ' ';
} else {
$set_sql .= '? ';
$bindings[] = $item[$u_col];
}
}
$set_sql .= 'ELSE `' . $u_col . '` END ';
$sets[] = $set_sql;
}
$update_sql .= implode(', ', $sets);
$where_in = collect($list_item)->pluck($reference_col)->values()->all();
$bindings = array_merge($bindings, $where_in);
$where_in = rtrim(str_repeat('?,', count($where_in)), ',');
$update_sql = rtrim($update_sql, ', ') . ' WHERE `' . $reference_col . '` IN (' . $where_in . ')';
//
$count += \DB::update($update_sql, $bindings);
}
return $count;
}
}
在 Laravel 中,DB::table 和 Db::table 實際上是相同的,它們都是用于創(chuàng)建數(shù)據(jù)庫查詢構建器(Database Query Builder)實例的方法。
DB::table 是 Laravel 提供的默認的數(shù)據(jù)庫查詢構建器門面(Facade)類方法,而 Db::table 是在 Laravel 8.x 版本中引入的全局輔助函數(shù)(Global Helper Function)。
————FROM CHATGPT
laravel update 那是什么語句 ?