将varchar转换为Decimal Arithmetic转换为数据类型numeric时发生溢出错误



请有人帮我处理这个简单的sql查询

SELECT avg(CAST(NULLIF(Sim1SS,0.0) as DECIMAL)) as MTN ,
avg(CAST(NULLIF(Sim2SS,0.0) as DECIMAL)) as Vodacom
FROM [Networks].[dbo].[Device] 

我得到以下错误:

将varchar转换为数据类型numeric时发生算术溢出错误。

这里是SS列的一个例子:

28,99
10,99
11,99
NULL
NULL
31,99
31,99
NULL

您有两个问题。首先,当您对字符串数据类型使用NULLIF时,您将隐式地将其转换为数字数据类型。您已指定0.0作为第二个参数。SQL Server不知道该选择什么,它可能选择了float或其他什么。将字符串转换为数字后,应调用NULLIF

其次,您还没有指定DECIMAL数据类型的精度和小数位数。根据MSDN,DECIMAL数据类型的默认精度和小数位数为18,0。如果未指定小数位数,则数字将被截断。

因此,正确的语法应该是:

SELECT avg(NULLIF(CAST(Sim1SS as DECIMAL(18,2)), 0.00)) as MTN,
       avg(NULLIF(CAST(Sim2SS as DECIMAL(18,2)), 0.00)) as Vodacom
FROM [Networks].[dbo].[Device] 

顺便说一句,如果你的十进制符号的区域设置不是句点(.),那么你需要做一个替换:

SELECT avg(NULLIF(CAST(REPLACE(Sim1SS, ',', '.') as DECIMAL(18,2)), 0.00)) as MTN,
       avg(NULLIF(CAST(REPLACE(Sim2SS, ',', '.') as DECIMAL(18,2)), 0.00)) as Vodacom
FROM [Networks].[dbo].[Device] 

如果你的数据没有被净化,你需要使用ISNUMERIC函数,如下所示:

SELECT avg(NULLIF(case when isnumeric(Sim1SS)=1 then CAST(REPLACE(Sim1SS, ',', '.') as DECIMAL(18,2)) end, 0.00)) as MTN,
       avg(NULLIF(case when isnumeric(Sim2SS)=1 then CAST(REPLACE(Sim2SS, ',', '.') as DECIMAL(18,2)) end, 0.00)) as Vodacom
FROM [Networks].[dbo].[Device] 

最新更新