mysql批量一次更新多个记录

问题描述

我有以下数据:

id  table   column add edit delete view
1   vendors city    0   0   0      1
1   vendors state   0   0   0      1
1   vendors zip     0   0   0      1

我正在尝试使用类似的查询执行批量更新:

UPDATE user_perms SET add = ?,edit = ?,delete = ?,view = ?
WHERE id = ? AND table_name = ? AND column_name = ?

MysqL不必遍历列表并运行X次此查询,是否支持一种一次性批量更新的方法

创建表STMT:

CREATE TABLE `user_perms` (
   `up_id` int unsigned NOT NULL AUTO_INCREMENT,`id` int unsigned DEFAULT NULL,`table_name` varchar(255) DEFAULT NULL,`column_name` varchar(255) DEFAULT NULL,`add` int unsigned DEFAULT NULL,`edit` int unsigned DEFAULT NULL,`delete` int unsigned DEFAULT NULL,`view` int unsigned DEFAULT NULL,PRIMARY KEY (`up_id`),UNIQUE KEY `up_id_UNIQUE` (`up_id`),KEY `fk_idx` (`id`),CONSTRAINT `fk_id` FOREIGN KEY (`id`) REFERENCES `users` (`user_id`) ON DELETE CASCADE
 ) ENGINE=InnoDB AUTO_INCREMENT=1659 DEFAULT CHARSET=utf8

解决方法

对于您来说,更新多行最接近的方法是使用CASE表达式设置值:

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
  <tr>
    <td class="text-right">A</td>
    <td>
      <div class="custom-control custom-checkbox">
        <input type="checkbox" class="custom-control-input" name="custom{{ $invoice->id }}" id="custom{{ $invoice->id }}">
        <label class="custom-control-label" for="custom{{ $invoice->id }}"></label>
      </div>
    </td>
    <td>
      <div class="form-row justify-content-center">
        <div class="form-group mb-0">
          <div class="input-group mx-auto mb-0">
            <div class="number-input amount">
              <!--just add minus class-->
              <button class="minus" onclick="this.parentNode.querySelector('input[type=number]').stepDown();" id="decrease"></button>
              <input class="quantity bg-light" id="quantity" min="0" placeholder="0" name="quantity" value="0" type="number">
              <button onclick="this.parentNode.querySelector('input[type=number]').stepUp();" class="plus" id="increment"></button>
            </div>
          </div>
        </div>
      </div>
    </td>
    <td class="cost">13
      <td class="total"></td>
  </tr>
  <tr>
    <td class="text-right">B</td>
    <td>
      <div class="custom-control custom-checkbox">
        <input type="checkbox" class="custom-control-input" name="custom{{ $invoice->id }}" id="custom{{ $invoice->id }}">
        <label class="custom-control-label" for="custom{{ $invoice->id }}"></label>
      </div>
    </td>
    <td>
      <div class="form-row justify-content-center">
        <div class="form-group mb-0">
          <div class="input-group mx-auto mb-0">
            <div class="number-input amount">
              <button class="minus" onclick="this.parentNode.querySelector('input[type=number]').stepDown();" id="decrease"></button>
              <input class="quantity bg-light" id="quantity" min="0" placeholder="0" name="quantity" value="0" type="number">
              <button onclick="this.parentNode.querySelector('input[type=number]').stepUp();" class="plus" id="increment"></button>
            </div>
          </div>
        </div>
      </div>
    </td>
    <td class="cost">135
      <td class="total"></td>
  </tr>
</table>

如果您想将UPDATE user_perms SET add = CASE column_name WHEN 'city' THEN ? WHEN 'state' THEN ? WHEN 'zip' THEN ? END,edit = CASE column_name WHEN 'city' THEN ? WHEN 'state' THEN ? WHEN 'zip' THEN ? END,delete = CASE column_name WHEN 'city' THEN ? WHEN 'state' THEN ? WHEN 'zip' THEN ? END,view = CASE column_name WHEN 'city' THEN ? WHEN 'state' THEN ? WHEN 'zip' THEN ? END WHERE id = ? AND table_name = ?; table_name都放在CASE表达式中,将会更加复杂。

坦率地说,编写循环并一次执行这一行会更容易。

例如,如果您有一个由列column_name组成的唯一键,以便SQL可以检测何时插入重复行,则可以执行以下操作:

(id,table_name,column_name)

如果这行得通,则无需先删除行。 INSERT .. ON DUPLICATE KEY UPDATE用于在您插入的数据与现有行不冲突的情况下插入新行,但是如果您插入的值与表上的唯一键冲突,则enter image description here仅更新您设置的那些列。 INSERT INTO user_perms (id,column_name,add,edit,delete,view) VALUES (1,'vendors','city',1),(1,'state','zip',1) -- any number of additional tuples follow ON DUPLICATE KEY UPDATE add = VALUES(add),edit = VALUES(edit),delete = VALUES(delete),view = VALUES(view); 子句。阅读文档以获取更多详细信息。