如果在SQL Server和SQL LocalDB上强制使用bigint,则行为会有所不同

问题描述

我在sql Server和LocalDB上具有以下功能

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的文章很多: