[數據庫/MySQL]解決異常:Data truncation: Truncated incorrect DOUBLE value: 'dc5'


1 場景復現

  • MySQL: 5.7.24-27
  • 表結構
    (兩張獨立的表)
[表 RRR1]
CREATE TABLE `RRR1` (
  `R1` float NOT NULL COMMENT 'R1',
  `R2` float NOT NULL COMMENT 'R2'
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='RRR1';

[表 Person11]
CREATE TABLE `Person11` (
  `CSSJY111` varchar(3) DEFAULT NULL COMMENT '測試數據元011',
  `CSSJY107` int(3) DEFAULT NULL COMMENT '測試數據元007',
  `CSSJY106` int(3) DEFAULT NULL COMMENT '測試數據元006',
  `CSSJY112` datetime DEFAULT NULL COMMENT '測試數據元012',
  `CSSJY103` varchar(10) DEFAULT NULL COMMENT '測試數據元003',
  `CSSJY113` blob COMMENT '測試數據元013',
  `CSSJY104` varchar(10) DEFAULT NULL COMMENT '測試數據元004',
  `CSSJY108` varchar(10) DEFAULT NULL COMMENT '測試數據元008',
  `CSSJY102` varchar(10) DEFAULT NULL COMMENT '測試數據元002',
  `CSSJY109` varchar(10) DEFAULT NULL COMMENT '測試數據元009',
  `CSSJY101` varchar(10) DEFAULT NULL COMMENT '測試數據元101',
  `CSSJY110` date DEFAULT NULL COMMENT '測試數據元010',
  `CSSJY105` int(3) DEFAULT NULL COMMENT '測試數據元005'
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='個人信息';
  • 異常SQL
DELETE FROM 
	CJ_TEST.`RRR1` 
		WHERE `R1` IN (  
			SELECT * FROM ( 
				SELECT `R1` FROM CJ_TEST.`RRR1` WHERE `R1` IN ( 
					SELECT `CSSJY111` FROM ( 
						SELECT `CSSJY111` FROM `CJ_TEST`.`Person11` ORDER BY `CSSJY112` ASC, `CSSJY111` LIMIT 3
					) ttt -- 中間表 ttt
				)
			) B WHERE B.R1 = 1 -- 中間表 B 
		)

報異常:

[Err] 1292 - Truncated incorrect DOUBLE value: 'dc5'

翻譯: [錯誤] 1292 - 數據截斷:截斷不正確的雙精度值:'dc5'

注: MySQL數據庫 必須帶中間表 ttt 和 B,否則 查詢會失敗

MySQL數據庫中 帶中間表 可避免異常:[Err] 1093 - You can't specify target table 'tableName' for update in FROM clause

FROM clause : FROM 子句

(翻譯: 你不能在DELETE/UPDATE這類修改操作的FROM子句中指定目標表——tableName。)
"不能先select出同一表中的某些值,再update這個表(在同一語句中)"
"不能在同一表中查詢的數據作為同一表的更新數據"
"注意,這個問題只出現於mysql,mssql和Oracle不會出現此問題。" (博主尚未驗證此結論)

原因: DELETE/UPDATE (修改)操作 表tableName時,其FROM子句的實際操作表是 FROM子句內的虛表(結果集)

解決辦法: 
1. 在select外邊套一層括號"( 原SQL )",讓數據庫認為你不是查同一表的數據作為同一表的更新數據
2. 將select的結果集臨時設置為中間表——`select * from ( 原select的結果集 ) TMP`,讓修改操作的FROM對象為中間表

詳見:MySQL之You can't specify target table for update in FROM clause解決辦法 - CSDN

2 原因分析

源字段與目標字段的類型不一致!!!

異常SQL中:
  源字段為    Person11表的CSSJY111字段(varchar(3))
  目標字段為  RRR1表的R1字段(float)

3 解決方案

情況1: 源字段值A與目標字段值B的類型不一致

  • 解決方案1

修改數據庫表的字段類型。

ALTER TABLE RRR1 MODIFY COLUMN R1 VARCHAR(3);
  • 解決方案2

sql_mode

(此方案不太推薦,但迫不得已時亦可使用)

SET SESSION sql_mode = '';

補充/延申: sql_mode的其它操作

select @@GLOBAL.sql_mode; 
select @@SESSION.sql_mode; -- STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION

SET SESSION sql_mode = 'STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION';

情況2: UPDATE的語法錯誤

網絡博客中很多人更多遇到的是此類情況————語法錯誤
例如:update table set A = "a" and B = "b" where id = 1 (報錯)

  • 解決方案

原SQL語句的 "and" 換成逗號 ","

update table set  A = "a" ,   B=  "b" where  id = 1 (正確)

Y 不足之處與反思

1 追根到底,本質上是什么原因導致的此異常? [√]
—— 此問題已解決 於 2020-10-14 21:14

2 sql_mode的配置起到了什么作用? [待解決]
3 為什么這么做可以成功解決? [√]
—— 此問題已基本解決 於 2020-10-14 21:14

X 參考與推薦文獻


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM