为什么不要让 SQLServer 帮你自动转换 SQL 命令中的数据类型
Report Date
:
|
Prepared by
:
郑
昀
|
Article last modified on
|
|
The information in this article applies to:
ü
Microsoft SQL Server 2000,7.0
|
问题陈述
:
有一天,执行
SELECT * FROM XXX_ORIGINAL_20031205
where
msgid
=62010388000012
语句,结果
SQL Server
报告出错:
“
将数据类型
varchar
转换为
numeric
时出错。
”
这是什么意思呢?
Msgid
这个字段的类型是:
varchar(30)
。
环境:
数据库服务器:
Microsoft SQL Server 2000
以及
7.0
;
数据库服务器补丁:
Microsoft SQL Server 2000 ServicePack1
;
原因分析:
不是
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
不是转换你的脚本命令中的数值,而是转换已有的历史数据到你指定的那个类型,所以会增加执行时间;第二,容易转换出错。
所以,切忌让
SQLServer
自己判断,自动帮你转换,那样将降低执行效率,而且增加出错几率。你能够显式告诉
SQL Server
你的数据类型的话,就请一定这么做。
Writen by zhengyun.NoJunk(at)tomosoft.dot.com
Disclaimers
:
本文档所包含的信息代表了在发布之日,
ZhengYun
对所讨论问题的当前看法,
Zhengyun
不保证所给信息在发布之日以后的准确性。
本文档仅供参考。对本文档中的信息,
Zhengyun
不做任何明示或默示的保证。
用户必须遵守所有适用的版权法。在不对版权法所规定的权利加以限制的情况下,如未得到
zhengyun
和
CSDN.Net
明确的书面许可,不得出于任何目的、以任何形式或手段(电子的、机械的、影印、录制等等)复制、传播本文的任何部分,也不得将其存储或引入到检索系统中。
Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=12744