将int字段改为decimal类型后出现1264 Out of range value的问题分析和处理之二
2016-12-18 22:14
549 查看
有开发同事在生产环境对某个表将int字段改成decimal(10,4)后,提示 1264 Out of range value报错,且原来值为负数,更改字段类型后,全部变为0,咨询dba这个为什么会报错,对数据有什么影响?
我收到这问题后,第一反应就是由于字段类型转换,长度不够发生了数据溢出。
于是,下面对模拟该问题进行测试:
1.建测试表
CREATE TABLE `zeng1` (
`_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
`a` int(32) DEFAULT NULL,
PRIMARY KEY (`_id`)
) ENGINE=InnoDB AUTO_INCREMENT=28129 DEFAULT CHARSET=utf8 ;
2.准备测试用数据
insert into zeng1(a) values (70000);
insert into zeng1(a) values (-123);
insert into zeng1(a) values (-10);
select * from zeng1;
+-------+-------+
| _id | a |
+-------+-------+
| 28129 | 70000 |
| 28130 | -123 |
| 28131 | -10 |
+-------+-------+
3.修改字段类型
alter table zeng1 modify column a decimal(10,4) unsigned;
Query OK, 3 rows affected, 2 warnings (0.03 sec)
Records: 3 Duplicates: 0 Warnings: 2
4.查看warnings
(product)root@localhost [midea_gls]> show warnings;
+---------+------+--------------------------------------------+
| Level | Code | Message |
+---------+------+--------------------------------------------+
| Warning | 1264 | Out of range value for column 'a' at row 2 |
| Warning | 1264 | Out of range value for column 'a' at row 3 |
+---------+------+--------------------------------------------+
2 rows in set (0.00 sec)
上面显示第2和第3行发生了数据溢出。
5.查询类型更改后的数据
select * from zeng1;
+-------+------------+
| _id | a |
+-------+------------+
| 28129 | 70000.0000 |
| 28130 | 0.0000 |
| 28131 | 0.0000 |
+-------+------------+
3 rows in set (0.00 sec)
第四和第五行的a字段记录发生了溢出。应更改将字段定义为带符号的,修改字段如下:
alter table zeng1 modify column a decimal(10,4);
再把数据update:
update zeng1 set a=-123 where `_id`= 28130;
update zeng1 set a=-10 where `_id`= 28131;
查看变为正常了:
select * from zeng1;
+-------+------------+
| _id | a |
+-------+------------+
| 28129 | 70000.0000 |
| 28130 | -123.0000 |
| 28131 | -10.0000 |
+-------+------------+
3 rows in set (0.00 sec)
decimal(10,4)的取值范围为-999999.9999到999999.9999,decimal(10,4)中的10表示全部位数为10(整数位+小数位),4表示小数位。
show warnings看到out of range表示超过了(小于最小值或大于最大值)这个值 ,建议生产环境在对一个表更改字段前,先对这个表的数据create table as select 来备份一份,若出现out of range时,
该记录的数据将全部变成0或9。
1.确保decimal(M,N)中M-N>=max(length(a)),在更改前可以查询字段a值的最大长度:
select max(length(a)) from zeng1;
2.确保有负数值的字段定义为带符号的,decmial默认为带符号,即不加 unsigned。检查字段a是否有负数值,用下面查询检查:
select count(*) from zeng1 where a like '-%',若返回值大于0,表示存在负数。
若前面在更改字段前,先对表进行了备份,表名为zeng1_bak,更改字段后,如何将数据更新回去?
select * from zeng1;
+-------+------------+
| _id | a |
+-------+------------+
| 28129 | 70000.0000 |
| 28130 | 0.0000 |
| 28131 | 0.0000 |
+-------+------------+
3 rows in set (0.00 sec)
select * from zeng1_bak;
+-------+-------+
| _id | a |
+-------+-------+
| 28129 | 70000 |
| 28130 | -123 |
| 28131 | -10 |
+-------+-------+
更新如下:
update zeng1 a1 set a1.a=(
select b1.a from zeng1_bak b1 where b1.`_id`=a1.`_id` and b1.`_id` in (28130,28131));
select * from zeng1;
+-------+------------+
| _id | a |
+-------+------------+
| 28129 | 70000.0000 |
| 28130 | -123.0000 |
| 28131 | -10.0000 |
+-------+------------+
3 rows in set (0.00 sec)
我收到这问题后,第一反应就是由于字段类型转换,长度不够发生了数据溢出。
于是,下面对模拟该问题进行测试:
1.建测试表
CREATE TABLE `zeng1` (
`_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
`a` int(32) DEFAULT NULL,
PRIMARY KEY (`_id`)
) ENGINE=InnoDB AUTO_INCREMENT=28129 DEFAULT CHARSET=utf8 ;
2.准备测试用数据
insert into zeng1(a) values (70000);
insert into zeng1(a) values (-123);
insert into zeng1(a) values (-10);
select * from zeng1;
+-------+-------+
| _id | a |
+-------+-------+
| 28129 | 70000 |
| 28130 | -123 |
| 28131 | -10 |
+-------+-------+
3.修改字段类型
alter table zeng1 modify column a decimal(10,4) unsigned;
Query OK, 3 rows affected, 2 warnings (0.03 sec)
Records: 3 Duplicates: 0 Warnings: 2
4.查看warnings
(product)root@localhost [midea_gls]> show warnings;
+---------+------+--------------------------------------------+
| Level | Code | Message |
+---------+------+--------------------------------------------+
| Warning | 1264 | Out of range value for column 'a' at row 2 |
| Warning | 1264 | Out of range value for column 'a' at row 3 |
+---------+------+--------------------------------------------+
2 rows in set (0.00 sec)
上面显示第2和第3行发生了数据溢出。
5.查询类型更改后的数据
select * from zeng1;
+-------+------------+
| _id | a |
+-------+------------+
| 28129 | 70000.0000 |
| 28130 | 0.0000 |
| 28131 | 0.0000 |
+-------+------------+
3 rows in set (0.00 sec)
第四和第五行的a字段记录发生了溢出。应更改将字段定义为带符号的,修改字段如下:
alter table zeng1 modify column a decimal(10,4);
再把数据update:
update zeng1 set a=-123 where `_id`= 28130;
update zeng1 set a=-10 where `_id`= 28131;
查看变为正常了:
select * from zeng1;
+-------+------------+
| _id | a |
+-------+------------+
| 28129 | 70000.0000 |
| 28130 | -123.0000 |
| 28131 | -10.0000 |
+-------+------------+
3 rows in set (0.00 sec)
decimal(10,4)的取值范围为-999999.9999到999999.9999,decimal(10,4)中的10表示全部位数为10(整数位+小数位),4表示小数位。
show warnings看到out of range表示超过了(小于最小值或大于最大值)这个值 ,建议生产环境在对一个表更改字段前,先对这个表的数据create table as select 来备份一份,若出现out of range时,
该记录的数据将全部变成0或9。
1.确保decimal(M,N)中M-N>=max(length(a)),在更改前可以查询字段a值的最大长度:
select max(length(a)) from zeng1;
2.确保有负数值的字段定义为带符号的,decmial默认为带符号,即不加 unsigned。检查字段a是否有负数值,用下面查询检查:
select count(*) from zeng1 where a like '-%',若返回值大于0,表示存在负数。
若前面在更改字段前,先对表进行了备份,表名为zeng1_bak,更改字段后,如何将数据更新回去?
select * from zeng1;
+-------+------------+
| _id | a |
+-------+------------+
| 28129 | 70000.0000 |
| 28130 | 0.0000 |
| 28131 | 0.0000 |
+-------+------------+
3 rows in set (0.00 sec)
select * from zeng1_bak;
+-------+-------+
| _id | a |
+-------+-------+
| 28129 | 70000 |
| 28130 | -123 |
| 28131 | -10 |
+-------+-------+
更新如下:
update zeng1 a1 set a1.a=(
select b1.a from zeng1_bak b1 where b1.`_id`=a1.`_id` and b1.`_id` in (28130,28131));
select * from zeng1;
+-------+------------+
| _id | a |
+-------+------------+
| 28129 | 70000.0000 |
| 28130 | -123.0000 |
| 28131 | -10.0000 |
+-------+------------+
3 rows in set (0.00 sec)
相关文章推荐
- 将int字段改为decimal类型时出现1264 Out of range value的问题分析和处理
- Java中long类型直接赋值出现The literal xxxxxxxxxx of type int is out of range 问题的原因和解决方法
- 手机字段存储报错 :Warning Code : 1264 Out of range value for column 'buyer_tpl' at row 1
- 关于mysql 出现 1264 Out of range value for column 错误的解决办法
- 关于mysql 出现 1264 Out of range value for column 错误的解决办法
- 手机字段存储报错 :Warning Code : 1264 Out of range value for column ‘buyer_tpl’ at row 1
- ([Oracle][ODBC]Numeric value out of range.)Biztalk项目中Oracle适配器,目标字段有date类型时报错
- 关于mysql 出现 1264 Out of range value for column 错误的解决办法
- 关于mysql 出现 1264 Out of range value for column 错误的解决办法
- h2 DB的一个问题,关于类型--Numeric value out of range
- 插入数据库 出现 Data truncation: Out of range value adjusted for column 'id'....的问题
- python创建cocos2d-x出现list index out of range的问题解决方法
- mysql错误 Out of range value for column '字段' at row 1
- mysql 主从同步 Error 'Out of range value for column的问题
- “System.IndexOutOfRangeException”类型的异常在 Stores.dll 中发生,但未在用户代码中进行处理
- #1264 - Out of range value adjusted for column 'ID' at row 1
- 关于c# 引发了"system.indexOutofRangeException"类型异常,该怎么处理
- #1264 - Out of range value adjusted for column 'ID 【转】
- MySQL5错误 #1264 "Out of range value adjusted for column ..."
- Java 中The literal 078 of type int is out of range问题