【案例分析】-1213 A character to numeric conversion process failed.
一个ER复制环境中,之前运行的好好的,突然报了错误"ER encountered a fatal error while evaluating replicate er_repl1 SQLCODE:-1213 ISAMCODE:0",然后ER复制关闭,无法再启动。
从SQLCODE错误号-1213可知,错误原因是:
1 2 3 4 5 6 7 8 9 10 | -1213 A character to numeric conversion process failed. A character value is being converted to numeric form for storage in a numeric column or variable. However, the character string cannot be interpreted as a number. It contains some characters other than white space, digits, a sign, a decimal, or the letter e; or the parts are in the wrong order, so the number cannot be deciphered. If you are using NLS, the decimal character or thousands separator might be wrong for your locale. |
即字符转换成数值失败。
通过查询该复制的语句,简单SELECT语句,只有一个WHERE条件
1 | select ... from ... where mkt = 0065; |
看起来也没什么语义问题。咦~!等等! mkt = 0065 ?!
这个字段怎么没用引号?这里当数值型处理了?
检查该表的表结构,mkt字段明确是varchar(10) 。
那么问题的原因也就明确了:
- 1,mkt = 0065 这语句会隐式的将mkt转换成数值型,然后再与0065进行比较;
- 2,当mkt字段中的列均能正常转换成数值型时,该语句能正常执行;
- 3,当mkt字段中新增加了不能隐式转换成数值型列时,如006A,该语句就会报错了。
知道了原因,解决方法就有了:
删除并重建该复制,where 条件改成 mkt = '0065',再重启复制即可。
原理上:当字段直接等于数值型时,会隐式的将字段转换成数值型,再与数值进行比较。因此,在编写SQL语句时:字段类型与比较的类型一致。否则可能带来隐患。
示例:
创建表tab2
1 2 3 4 5 6 7 | create table tab2 ( uid serial primary key , uname varchar (40), upass varchar (40) ); insert into tab2 values (0, '000' , 'password000' ); insert into tab2 values (0, '001' , 'password001' ); |
此时,通过语句
1 | select * from tab2 where uname = 001; |
能正常执行
1 2 3 4 5 | uid 2 uname 001 upass password001 1 row(s) retrieved. |
但如果我们再插入一行:
1 | insert into tab2 values (3, 'U03' , 'passwordU03' ); |
此时的数据为:
1 2 3 4 5 6 7 8 9 10 11 12 13 | uid 1 uname 000 upass password000 uid 2 uname 001 upass password001 uid 3 uname U03 upass passwordU03 3 row(s) retrieved. |
再次执行查询语句,则会报错:
1 2 3 4 5 | > select * from tab2 where uname = 001; 1213: A character to numeric conversion process failed Error in line 1 Near character position 35 |
总结:字段比较应当类型匹配,否则会带来隐患!