1

mysql> update tablename set fieldname = 'C200900674' where fieldname - 'C200900673';

错误 1062 (23000):密钥 1 的重复条目“C200900674-2008-0-1”

对此有何想法或建议?我们有人不小心用减号而不是等号进行了更新。它显然试图更改小于该值的所有记录?即使它是字母数字的并且确实相当不完整。最重要的是,在出现该错误之前已更新了许多记录,并且根本没有任何反馈。没有像“查询正常,X 行受影响(0.00 秒)”这样的东西,所以我们不知道有多少被改变了。autocommit=1 所以无法回滚。

无论如何,只是寻找有关此的任何提示或指示。为什么该查询根本没有做任何事情,它看起来确实应该向我返回一个错误。当然,除了不让没有经验的管理员做愚蠢的事情的明显答案之外。

4

2 回答 2

2

每当对 Mysql 如何解释 WHERE 子句有疑问时,将其反转为 SELECT。

SELECT fieldname - 'C200900673' FROM tablename;

和:

SELECT fieldname FROM tablename WHERE fieldname - 'C200900673';

查看第一个选择返回什么值,以及第二个选择返回什么行。

可悲的是,由于 Mysql 在数字/字符串转换方面非常松懈,特别是在 4.x 系列上,甚至在非严格的 5.x 上,哎呀......即使是严格模式,也很难准确地说出哪里出了问题您的 Mysql 配置的详细信息。这可能是因为 fieldname 被强制转换为某个数字,'C200900673' 也是如此,基本上运行:

update tablename set fieldname = 'C200900674' where NUMBER - NUMBER;

这可以转化为:

update tablename set fieldname = 'C200900674' where 1;

无论如何,我希望你有一个备份!

于 2009-06-30T07:23:02.337 回答
0

如果您的表使用 InnoDB 存储引擎,则不会造成任何损害。即使使用 autocommit=1,查询也只会“全有或全无”执行。您收到错误消息的事实证明数据库没有触及您的数据。每当您收到错误消息时,都会省略“受影响的 x 行”消息。

即使没有违反唯一性约束,查询也会失败并出现不同的错误:

错误 1292 (22007):截断不正确的 DOUBLE 值:'fieldname'

这是因为减号会导致 MySQL 尝试计算字段内容的值减去其他值。这不起作用。你只是没有看到这个错误,因为另一个“先到那里”。

于 2009-05-20T12:32:34.230 回答