问题描述
我有以下数据:
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用于在您插入的数据与现有行不冲突的情况下插入新行,但是如果您插入的值与表上的唯一键冲突,则仅更新您设置的那些列。 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);
子句。阅读文档以获取更多详细信息。