zoukankan      html  css  js  c++  java
  • [数据库/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 参考与推荐文献

  • 相关阅读:
    python工具类 md5
    python 线程池, 进程池
    scrapydweb 安装部署
    python 协程
    jquery
    scrapyd 设置访问密码
    pat 乙级1033 旧键盘打字(20)
    1459 迷宫游戏(51NOD)
    python之禅
    Jzzhu and Cities ----CodeForces
  • 原文地址:https://www.cnblogs.com/johnnyzen/p/13817084.html
Copyright © 2011-2022 走看看