英文:
Is there a better way to update as multiple records in Laravel?
问题
我对这个主题进行了一些研究,但最后我发现我的方法对于更新约100个记录 x 10个字段的列表是可接受的。是否有更好的方法?
这些数组来自一个类似于以下形式的表单:
<div class="input-group">									
    <div class="col-1">
       <input class="input" type="text" name="id[]" id="id[]" value="...">
    </div>	
    <div class="col-1">
       <input class="input" type="text" name="field1[]" id="field1[]" value="...">
    </div>	
    <div class="col-1">
       <input class="input" type="text" name="field2[]" id="field2[]" value="...">
    </div>	
    <div class="col-1">
       <input class="input" type="text" name="field3[]" id="field3[]" value="..">
    </div>	
    ...
</div>
为了保存数据库表中的所有更改,我在控制器中执行以下PHP代码:
// 批量更新数据库 | PUT
public function save($table, $fields='field1,field2,field3...')
{
    // 替换SQL语句
    $sqlReplace0 = "UPDATE ".$table." SET XXX_listFields WHERE id = ";
    // 将字段列表转换为数组
    $arrayFields = explode(',', $fields);
    // 循环记录
    $sql = '';
    $i = 0;
    foreach($_POST['id'] as $id) {
        // 循环字段
        $fields = '';
        foreach($arrayFields as $field) {
            if ($fields == '') {
                $fields .= $field." = '".$_POST[$field][$i]."'";
            } else {
                $fields .= ",".$field." = '".$_POST[$field][$i]."'";
            }
        }
        // 替换SQL中的字段和值
        $sql .= str_replace('XXX_listFields', $fields, $sqlReplace0)."'".$id."';\n";
        $i++;
    }
    // 更新所有记录
    $result = DB::unprepared($sql); 
    ...
}
在我的情况下,这个方法运行得相当快...但我想知道是否有更好的方法...
英文:
I did some research on the subject but at the end I found that my approach was acceptable for updating about a list of 100 records x 10 fields. Is there a better way to do that?
The arrays come from a form looking like this:
 <div class="input-group">									
    <div class="col-1">
       <input class="input" type="text" name="id[]" id="id[]" value="...">
    </div>	
    <div class="col-1">
       <input class="input" type="text" name="field1[]" id="field1[]" value="...">
    </div>	
    <div class="col-1">
       <input class="input" type="text" name="field2[]" id="field2[]" value="...">
    </div>	
    <div class="col-1">
       <input class="input" type="text" name="field3[]" id="field3[]" value="..">
    </div>	
    ...
 </div>
In order to save all the changes in the db table, I execute the following PHP in the controller:
 //  update db in bulk | PUT
 public function save($table,$fields='field1,field2,field3...')
 {
    // replace sql statement
    $sqlReplace0 = "UPDATE ".$table." SET XXX_listFields WHERE id = ";
    // fields list into array
    $arrayFields = explode(',',$fields);
    // loop records
    $sql = '';
    $i = 0;
    foreach($_POST['id'] as $id) {
       // loop fields
       $fields = '';
       foreach($arrayFields as $field) {
          if ($fields == '') {
             $fields .= $field." = '".$_POST[$field][$i]."'";
          } else {
             $fields .= ",".$field." = '".$_POST[$field][$i]."'";
          }
       }
       // replace fields & values in sql
       $sql .= str_replace('XXX_listFields',$fields,$sqlReplace0)."'".$id."';\n";
       $i++;
    }
    // update all records
    $result = DB::unprepared($sql); 
    ...
 }
It works pretty fast in my case... but I would like to learn if there is a better way...
答案1
得分: 1
为了回答你的问题,你可以使用 Laravel 的 upsert 功能。
以下是一个 upsert 的示例:
YourModelName::upsert([
    ['firstfield' => 'request var', 'secondfield' => 'request var', 'thirdfield' => 'request var'],
    ['firstfield' => 'request var', 'secondfield' => 'request var', 'thirdfield' => 'request var']
], ['firstfield']);
upsert 用作更新或创建方法,如果数据与数据库中的记录匹配(在这种情况下我们使用 firstfield),则记录将被更新,如果没有匹配,则将其插入为新行。
你还可以通过循环将变量存储在集合中,然后将其传递给 upsert 方法。
以下是一个示例:
$data = [];
for ($i = 0; $i < count($request->id); $i++){
    $data[] = [
        'id'     => $request->input('id')[$i],
        'field1' => $request->input('field1')[$i],
        'field2' => $request->input('field2')[$i],
        'field3' => $request->input('field3')[$i]
    ];
}
YourModelName::upsert($data, ['id']);
希望这有所帮助。
英文:
To answer you question, you can use the upsert feature of Laravel.
here's an example of upsert:
YourModelName::upsert([
    ['firstfield' => 'request var', 'secondfield' => 'request var', 'thirdfield' => 'request var'],
    ['firstfield' => 'request var', 'secondfield' => 'request var', 'thirdfield' => 'request var']
],  ['firstfield']);
upsert serves as an update or create method, if the data matched with a record in your database (which in this case we use firstfield) than the record will be updated, and if not, then it will be inserted as a new row.
you can also run your variables through a loop, and store them in a collection and then pass it to the upsert method.
here's an example:
$data = [];
for ($i = 0; $i < count($request->id); $i++){
    $data[] = [
        'id'     => $request->input('id')[$i],
        'field1' => $request->input('field1')[$i],
        'field2' => $request->input('field2')[$i],
        'field3' => $request->input('field3')[$i]
    ];
}
YourModelName::upsert($data, ['id']);
hope it helps.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论