【问题标题】:Arithmetic overflow error converting nvarchar to data type numeric error with MAX使用 MAX 将 nvarchar 转换为数据类型数值错误的算术溢出错误
【发布时间】:2018-09-13 19:20:32
【问题描述】:
  SELECT x.Key, x.ID,
  MAX(CAST(CASE WHEN x.Display IS NULL THEN 0
  WHEN x.Display = 'Class' THEN 0
 WHEN x.Display = 'pricing' THEN 0
 WHEN x.Display = 1912.995 THEN 1913
 ELSE x.Display END as float)) AS GLwritten
 FROM x
 inner join y on y.rk_pk = x.pk
 group by x.Key, x.ID

如果我没有输入 WHEN x.Display = 1912.995 THEN 1913,则会出现以下错误: 将 nvarchar 值“1912.995”转换为数据类型 int 时转换失败。

x.Display 是 nvarchar。 不幸的是,我无法控制该列的设计。

错误是在将 nvarchar 值 '1912.995' 转换为数据类型 int 时转换失败。

【问题讨论】:

  • 那是因为您将数字和字符串存储在同一列中。您必须将其更改为 ...when x.Display = '1912.995' then...而且您真的应该考虑在这里重新设计。
  • no SQL Server 2010 - 我们有 2000、2005、2008、2008 R2、2012、2014、2016 和 2017 - 拿你的选择...

标签: sql-server


【解决方案1】:

您确实应该避免在同一列中存储混合数据类型。

也就是说,我假设您的 x.Display 的其他值可以转换为 FLOAT。您需要在 CASE 语句的每个部分使用相同的数据类型,然后 CAST 才能工作。

DECLARE @x TABLE (Display NVARCHAR(MAX));
INSERT @x (Display) VALUES ('Class');
INSERT @x (Display) VALUES ('pricing');
INSERT @x (Display) VALUES ('1912.995');
INSERT @x (Display) VALUES ('123.456');

SELECT
    MAX(
        CAST(
            CASE WHEN x.Display IS NULL THEN '0'
            WHEN x.Display = 'Class' THEN '0'
            WHEN x.Display = 'pricing' THEN '0'
            ELSE x.Display END
        AS FLOAT)
    ) AS GLwritten
FROM @x x

【讨论】:

    【解决方案2】:

    CASE 表达式的类型是具有最高优先级的值的类型。在这种情况下,这些值为 0001983Display。这些类型为intintintintnvarchar。由于int 的优先级高于nvarchar,因此CASE 表达式的类型为int。因此,当您尝试将带小数点的值转换为 int 时,它会失败。

    请注意,float 的优先级高于 int。因此,如果您可以将其中一个值设为float,那么整个CASE 表达式的值将是float

    这样做的一种方法是将第一个0 替换为cast(0 as float)CASE 的值将是float,字符串转换将起作用。

    create table x ( Display nvarchar(20)     );
    
    insert into x ( Display ) values
    ( NULL         ),
    ( 'Class'      ),
    ( 'pricing'    ),
    ( '1912.995'   ),
    ( '3.14159265' ),
    ( '2000'       )
    
      SELECT CASE WHEN x.Display IS NULL THEN 0
      WHEN x.Display = 'Class' THEN cast ( 0 as float ) -- <<<===
     WHEN x.Display = 'pricing' THEN 0
     WHEN x.Display = 1912.995 THEN 1913
     ELSE x.Display END AS GLwritten
     FROM x
    

    【讨论】:

    • 您觉得这有帮助吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-18
    相关资源
    最近更新 更多