昨天我们在用的系统,报了一个错误,很奇怪:“转换 varchar 值 '157975392974595800' 时溢出了整数列。
一时半会,我还真没反应过来是什么问题,当时我的第一感觉就是,类型转换问题,只是到底错误在哪里,还是不清楚。
因为代码是别人写的,恰巧维护代码的人有事,给我发了份代码过来,让我自己调。
“坑”,就这样发生了。我们调了半天,才发现错误是这样的:
背景:
1.表CM_Department2.主键cguid,且cguid值是varchar(18)
Java里的代码如下:
sql.append("charindex(cfullcode"+tempStr);
sql.append(", (select cfullcode from "+tableName + " where cguid={"+key+"})"+tempStr+")=1 )")
这段代码主要是拼接处一个SQL,那么拼出来的这个SQL会不会报错,有没有隐患?
看下这个拼接处的SQL部分代码如下:
select cfullcode from CM_Department where cguid={cdeptguid}
这个SQL是否有问题?
那再看下面的SQL:
select cfullcode from CM_Department where cguid=000000
我们经常写的SQL是这样:
select cfullcode from CM_Department where cguid='000000'
发现问题所在了吧!
这个SQL:
select cfullcode from CM_Department where cguid=000000
假如:
1.数据库表CM_Department的cguid列的值是一位或者二位数字,亦或者是只要不超过2147483648(int最大值),都行
这种情况下是不会报错的
2.数据库表CM_Department的cguid列的值是18位数字,即超过了int最大值,就会报错:“转换 varchar 值 '157975392974595800' 时溢出了整数列。”
总结:
1.SQLSERVER作比较时,是转换成相同类型来比较的;
比如:cguid=000000,sqlserver会把cguid列值取出来转换成数值型,然后再跟数值型000000作比较。
而当cguid列值出现超过整型最大值时,自然就会溢出。
比如:cguid='000000',因为cguid本身就是字符型的,后面的'000000'也是字符型,不需要转型,直接比较就行。
切记:
Java里拼接SQL,切记变量加引号。