问题描述
CREATE FUNCTION [dbo].[ConvertToLong]
(
@Value Varchar(200)
)
RETURNS Bigint
AS
BEGIN
If ISNUMERIC(@Value)<>1
Return 0
Else
Return Cast(@Value as bigint)
Return 0
END
SELECT dbo.[ConvertToLong]('13668433347')
我收到不同的结果:
sqlServer:
13668433347
LocalDB:
Arithmetic overflow error converting expression to data type int.
任何想法是什么问题以及如何为LocalDB修复它?
解决方法
这里的问题是您正在尝试重新发明轮子。每个受支持的SQL Server版本都具有函数TRY_CONVERT
,如果无法转换该值,该函数将返回NULL
。
ISNUMERIC
也是非常有缺陷的。 ISNUMERIC('1.23')
和ISNUMERIC('7e2')
之类的内容返回1
,但是CONVERT(int,'1.23')
和CONVERT(decimal(10,2),'7e2')
均失败。同样,ISNUMERIC('')
返回0
,但是CONVERT(tinyint,'')
返回0
,不是错误。
结果是,答案是使用内置函数TRY_CONVERT
(或TRY_CAST
):
SELECT TRY_CONVERT(bigint,'13668433347');
如果要在发生转换错误时返回0
,则可以使用ISNULL
,并且如果要保留NULL
值,请使用CASE
表达式。像这样:
SELECT CASE WHEN YourColumn IS NOT NULL THEN ISNULL(TRY_CONVERT(bigint,YourColumn),0) END;
关于为什么也应避免使用ISNUMERIC
的文章很多: