2009-05-20 87 views
1

mysql> update tablename set fieldname ='C200900674'where fieldname - 'C200900673';MySQL UPDATE行爲

ERROR 1062(23000):重複項 'C200900674-2008-0-1' 關鍵1個

對此有何想法或建議?我們有人不小心用負號代替等號進行更新。它顯然試圖改變所有小於該值的記錄?儘管它是字母數字式的,並且非常不完整。最重要的是,一些記錄在得到該錯誤之前進行了更新,並且根本沒有任何反饋。沒有什麼比「查詢OK,X行受到影響(0.00秒)」,所以我們不知道有多少人改變了。 autocommit = 1所以沒有能力回滾。

無論如何,只是尋找任何提示或指針就可以了。爲什麼那個查詢確實是什麼,它真的看起來應該向我返回一個錯誤。除了不讓缺乏經驗的管理員做一些頭腦事情的明顯答案。

回答

0

如果您的表使用的是InnoDB存儲引擎,則不會造成任何損害。即使autocommit = 1,查詢也只能執行「全有或全無」。 您收到錯誤消息的事實證明數據庫未觸及您的數據。無論何時出現錯誤,「x rows affected」消息都會被省略。

即使萬一uniquess約束也不會被違反的查詢會失敗,不同的錯誤:

ERROR 1292 (22007): Truncated incorrect DOUBLE value: 'fieldname'

這是因爲減號會造成MySQL的嘗試和計算的價值字段內容減去別的東西。這不起作用。你只是沒有看到這個錯誤,因爲另一個「首先到達那裏」。

+1

該表位於INNODB中,顯然我們*經歷了正在更改的記錄數量。迄今爲止我所能發現的所有證據都指出了這一點。在此框中啓用了二進制日誌記錄,以便挖掘甚至包含「mysqlbinlog -s {logfile} | grep -i {該記錄的唯一標識符}」。更新語句*的FWIW也記錄在binlog中。我將繼續玩這個,並可能嘗試製作測試數據庫和一些表格,並嘗試在受控環境中重現它。謝謝... – wdingus 2009-05-20 14:07:20

2

每當有人懷疑Mysql如何解釋WHERE子句時,將其反轉爲SELECT。

SELECT fieldname - 'C200900673' FROM tablename; 

和:

SELECT fieldname FROM tablename WHERE fieldname - 'C200900673'; 

看到的是第一選擇,而第二個查找行返回什麼價值。

不幸的是,由於Mysql在數字/字符串轉換上相當鬆懈,特別是在4.x系列上,甚至在非嚴格5.x上,甚至嚴格模式,很難準確地說出什麼沒有你的Mysql配置的所有細節就出錯了。這可能是因爲字段名被摔了一些數字,等於是「C200900673」,基本上是運行:

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

哪位能翻譯成:

update tablename set fieldname = 'C200900674' where 1; 

無論如何,我希望你有一個備份!