有没有更好的方法来在Laravel中更新多个记录?

huangapple go评论65阅读模式
英文:

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:

 &lt;div class=&quot;input-group&quot;&gt;									
    &lt;div class=&quot;col-1&quot;&gt;
       &lt;input class=&quot;input&quot; type=&quot;text&quot; name=&quot;id[]&quot; id=&quot;id[]&quot; value=&quot;...&quot;&gt;
    &lt;/div&gt;	
    &lt;div class=&quot;col-1&quot;&gt;
       &lt;input class=&quot;input&quot; type=&quot;text&quot; name=&quot;field1[]&quot; id=&quot;field1[]&quot; value=&quot;...&quot;&gt;
    &lt;/div&gt;	
    &lt;div class=&quot;col-1&quot;&gt;
       &lt;input class=&quot;input&quot; type=&quot;text&quot; name=&quot;field2[]&quot; id=&quot;field2[]&quot; value=&quot;...&quot;&gt;
    &lt;/div&gt;	
    &lt;div class=&quot;col-1&quot;&gt;
       &lt;input class=&quot;input&quot; type=&quot;text&quot; name=&quot;field3[]&quot; id=&quot;field3[]&quot; value=&quot;..&quot;&gt;
    &lt;/div&gt;	
    ...
 &lt;/div&gt;

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=&#39;field1,field2,field3...&#39;)
 {

    // replace sql statement
    $sqlReplace0 = &quot;UPDATE &quot;.$table.&quot; SET XXX_listFields WHERE id = &quot;;

    // fields list into array
    $arrayFields = explode(&#39;,&#39;,$fields);

    // loop records
    $sql = &#39;&#39;;
    $i = 0;
    foreach($_POST[&#39;id&#39;] as $id) {

       // loop fields
       $fields = &#39;&#39;;
       foreach($arrayFields as $field) {
          if ($fields == &#39;&#39;) {
             $fields .= $field.&quot; = &#39;&quot;.$_POST[$field][$i].&quot;&#39;&quot;;
          } else {
             $fields .= &quot;,&quot;.$field.&quot; = &#39;&quot;.$_POST[$field][$i].&quot;&#39;&quot;;
          }
       }

       // replace fields &amp; values in sql
       $sql .= str_replace(&#39;XXX_listFields&#39;,$fields,$sqlReplace0).&quot;&#39;&quot;.$id.&quot;&#39;;\n&quot;;

       $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([
    [&#39;firstfield&#39; =&gt; &#39;request var&#39;, &#39;secondfield&#39; =&gt; &#39;request var&#39;, &#39;thirdfield&#39; =&gt; &#39;request var&#39;],
    [&#39;firstfield&#39; =&gt; &#39;request var&#39;, &#39;secondfield&#39; =&gt; &#39;request var&#39;, &#39;thirdfield&#39; =&gt; &#39;request var&#39;]
],  [&#39;firstfield&#39;]);

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 &lt; count($request-&gt;id); $i++){
    $data[] = [
        &#39;id&#39;     =&gt; $request-&gt;input(&#39;id&#39;)[$i],
        &#39;field1&#39; =&gt; $request-&gt;input(&#39;field1&#39;)[$i],
        &#39;field2&#39; =&gt; $request-&gt;input(&#39;field2&#39;)[$i],
        &#39;field3&#39; =&gt; $request-&gt;input(&#39;field3&#39;)[$i]
    ];
}

YourModelName::upsert($data, [&#39;id&#39;]);

hope it helps.

huangapple
  • 本文由 发表于 2023年5月28日 19:57:16
  • 转载请务必保留本文链接:https://go.coder-hub.com/76351365.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定