SQLServer有很强的格式自动转换功能,但是他不是万能的,有些时候也是转换不了的,而且出现错误我们很难查找,因为我们有些时候是可以的,有些时候又出现问题。正确之时都是SQLServer格式转换范围内的,那些超出界限的,就会出现错误,而出现错误的时候,我们的程序员就会陷入一个误区:检查别的地方代码,而且为此浪费很多的时间,贻误了工程进度,对项目来说是有害的,对自己来说,更是有害的。下面有个例子,我们可以参考一下,借此说明此问题。
问题陈述:
有一天,执行
SELECT * FROM XXX_ORIGINAL_20031205
where msgid=62010388000012
语句,结果SQL Server报告出错:“将数据类型 varchar 转换为 numeric 时出错。”
这是什么意思呢?
Msgid这个字段的类型是:varchar(30)。
原因分析:
不是SQL Server突然不能从数字自动转换为字符串,而是单单对这个字段的数值有问题,这也和这个字段中实际已存储的字符串有关。
你看,我执行这个SQL语句是没有问题,可以自动转换:
SELECT * FROM XXXX_ORIGINAL_20031205
where recordid=62010388000012
recordid这个字段的类型也是:varchar(30)。
这为什么就可以呢?
为什么?
这是因为msgid字段的真实数值是类似于这样的字符串“12051113280101053509”,由于你的SQL命令中要求拿字符串跟我们提供的这个数字62010388000012匹配,所以SQLServer默认要把这么多个“12051113280101053509”先统统转换为数字,再去跟62010388000012匹配。
(首先这就涉及到一个效率问题,转换这么多msgid成为数字,再跟你的数字匹配,将是一个多么大的浪费啊)
当然,这回SQLServer转不过来了,因为“12051113280101053509”换为数字实在太大了,超出了范围,所以你看SQLServer于是乎报告“将数据类型 varchar 转换为 numeric 时出错”,他指的就是把历史数据“12051113280101053509”这个varchar(30)转成numeric不行,而不是把你SQL脚本传递的参数62010388000012转换失败。
让我们看看另一种形式的错误,就更清楚了:
我们执行
SELECT * FROM XXXX_ORIGINAL_20031205
where msgid=120
命令就会得到错误:
varchar 值 '12050003010101026986' 的转换溢出了 int 列。超出了最大整数值。
这个错误,是不是很清楚地表明了SQLServer在帮你执行SQL命令时背后所作的事情?
他试图帮你主动把记录中的这个字段转换成你在SQL命令中指明的那个数据类型。
总结:
很多时候,我们懒得去看某个字段到底是什么类型,是char,还是tinyint,还是bool,还是varchar,我们就随便写一个数字,让聪明的SQL Server自己去判断该转成什么。
再次我将聪明的SQL Server自动转换给我们带来的害处简单罗列:
1、增加出错次数,而且出现错误容易让我们陷入误区,让我们的程序不够健壮。
2、自动转换会增加SQL的执行时间,让我们的程序没有效率。
3、给我们程序带来无限隐患,为后期的功能延伸带来麻烦
建议:
不积硅步何以至千里,千里长堤溃于蚁穴。希望程序员兄弟们以次为鉴,自己勤快一点,养成一个好的习惯,在错误产生之前搞定他。请自己判断好格式,然后将数据传给SQLServer,因为相信机器,不如相信自己。