我有一个actor
表,如下所示:
| actor_id | first_name | last_name | last_update |
+----------+------------+-----------+---------------------+
| 1 | Jack | Nicholson | 2019-06-02 00:00:00 |
列actor_id
是具有自动递增功能的主键。
当我尝试像这样更新表时:
UPDATE actor
SET last_name = 'foo'
WHERE last_update > '2019-06-02 00:00:00';
我被MySQL的安全更新模式阻止,并出现以下错误:
错误代码:1175。您正在使用安全更新模式,并且试图在没有使用KEY列的WHERE的情况下更新表。要禁用安全模式,请在“首选项”->“ SQL编辑器”中切换选项,然后重新连接。
独立列last_update
不是KEY列,因此基于this SO answer,我提出了以下解决方法:
CREATE TEMPORARY TABLE IF NOT EXISTS ids AS (SELECT actor_id FROM actor WHERE last_update > '2019-06-02 00:00:00');
UPDATE actor
SET last_name = 'foo'
WHERE actor_id IN (SELECT actor_id FROM ids);
但是我再次遇到1175错误。
为什么安全更新模式在这里阻止了我?我可以在不禁用安全更新模式的情况下解决它吗?
答案 0 :(得分:2)
您可以通过将该列设置为KEY列来解决此错误。换句话说,在列上创建索引(又称键)。
mysql> set sql_safe_updates=ON;
mysql> UPDATE actor SET last_name = 'foo' WHERE last_update > '2019-06-02 00:00:00';
ERROR 1175 (HY000): You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column
mysql> alter table actor add key (last_update);
Query OK, 0 rows affected (0.04 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> UPDATE actor SET last_name = 'foo' WHERE last_update > '2019-06-02 00:00:00';
Query OK, 0 rows affected (0.00 sec)
Rows matched: 0 Changed: 0 Warnings: 0
错误的要点是,当您对非索引列有条件时,防止您无意中锁定表中的每一行。
锁定的工作方式,它锁定查询检查以测试条件的所有行,而不只是满足条件的所有行。如果您在查询条件下运行测试未索引查询的查询,则它必须检查表中的每一行,这可能比您预期的锁定方式更多。