使用主键时出现 MySQL 1175 错误

nih*_*lon 4 primary-key update errors mysql-5.6

什么会导致以以下开头的错误 1175:You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column...。我的问题是我确实包含了一个WHERE带有键列的子句:WHERE a.a_id = b.b_id

a_id并且b_id是各自表中唯一的键列。

START TRANSACTION;
    UPDATE table_a a, table_b b
    SET a.update_me = b.update_from_me
WHERE a.a_id = b.b_id;
SELECT * FROM a;
Run Code Online (Sandbox Code Playgroud)

我错过了什么?

Ion*_*nic 6

嗯,这很简单。

您已启用安全更新模式(如错误所述)。你的语句有一个 where 子句,对。但它被解释为 a JOINnot as ,WHERE因为您提供了类似 a 的语法INNER JOIN

您的代码:

UPDATE table_a a, table_b b
SET a.update_me = b.update_from_me
WHERE a.a_id = b.b_id;
Run Code Online (Sandbox Code Playgroud)

在技​​术上与此相同(并如此解释):

UPDATE a
FROM table_a a
INNER JOIN table_b b
        ON a.a_id = b.b_id;b_id
SET a.update_me = b.update_from_me;
Run Code Online (Sandbox Code Playgroud)

这意味着,没有真正的WHERE. 您更新table_a与另一个表匹配的整个表table_b

如果你真的想实现这一点,你可以Safe Update Mode使用以下代码禁用此查询:

SET SQL_SAFE_UPDATES=0;
UPDATE table_a a, table_b b
SET a.update_me = b.update_from_me
WHERE a.a_id = b.b_id;
Run Code Online (Sandbox Code Playgroud)

无论如何,您的 mysql 服务器正在运行,mysqld --safe-updates或者mysqld --i-am-a-dummy是完全相同的选项。

您可以使用以下命令之一检查是否真的启用了此功能:

SELECT @@SQL_SAFE_UPDATES
-- or
SHOW VARIABLES LIKE 'sql_safe_updates'
Run Code Online (Sandbox Code Playgroud)

顺便说一下,您也可以尝试一种解决方法来完成更新。Safe Update Mode需要一个WHERE或一个LIMIT。这将限制更新的影响。另一个想法可以是LIMIT为您的UPDATE.

UPDATE table_a a, table_b b
SET a.update_me = b.update_from_me
WHERE a.a_id = b.b_id
LIMIT 100000;
Run Code Online (Sandbox Code Playgroud)

如果Safe Update Mode启用了 ,您也需要注意DELETE's。他们两者都需要。一个WHERE和一个LIMIT。请参阅文档