今天一个朋友问了我一个问题,为什么在SQL Server中执行下面的语句会返回不应该的值。
Select ISNumeric('1d00') |
---|
根据我们的理解,这个应该是返回为0的。这个值明显不是数字类型嘛。但是奇怪的是,SQL Server就是返回的1.
通过Google,发现了在SQLServerCentral论坛上也有人提出了一个类似的问题,http://www.sqlservercentral.com/Forums/Topic243646-8-1.aspx
看了下,解释如下:
"D and E are used in Fortran to represent FLOATs in scientific notation. SQL Server internally uses C routines for ISNUMERIC that follow these formats. So ISNUMERIC returns 1 for 0d830 and 0e830, because they are evaluated to be convertible to FLOAT.
The reason why select convert(float,'0D830') returns 0 is simple. 0d830 is a shortcut to 0*10^830 which obviously is 0 for every INT you place after the d. "
也就是说在科学计数法中,是可以使用D或者E来表示Float的。在这里就说到了ISNumeric的原理其实就是并不直接对传入的数据进行判断,而是通过是否可以将该数据转化为numeric数据来进行判断。也就是说有些时候表象上看起来本不应该是数字类型的,其实是可以通过转成数字后,来确定到底该函数会返回什么值。根据这个原理,在传入的数据中带有'+', '-', 'd', 'e', '$','£'这些字符,都是返回为1的。
有兴趣的,可以测试下面的示例:
SELECT ISNUMERIC('1d8') -- 1
SELECT ISNUMERIC('1D8') -- 1
SELECT ISNUMERIC('1d') -- 0
SELECT ISNUMERIC('1D') -- 0
|
---|
--------------------------------------------------------
就结论而言ISNUMERIC是通过尝试转换传入的内容,是否能cast为其他类似Float类型,若报错就返回0,报错返回1的方式实现的。
所以我们的开发人员在开发程序写对应的判断条件的时候,一定要注意该点,避免出现不该有的Bug。