将数据类型varchar转换为浮于非varchar数据类型时出错

时间:2019-05-22 12:29:21

标签: sql casting coalesce

我遇到了一个问题(我已经部分解决了),但最初似乎找不到失败的原因。

我在表中有一个字段,其中包含字母和数字值的组合。该字段是char(20)数据类型(这是错误的,但不可更改),并包含 NULL值'Unknown'或“数字” 0、50、100 。字符字段用尾随空格填充值。这是已知的,我们对此无能为力。

要删除Unknown值,我们有一系列合并语句,这两个语句按照标题返回错误消息。

,coalesce(DHMCC.[HESA Module Total Proportion Taught], 'Missing')
,cast(isnull(DHMCC.[HESA Module Total Proportion Taught] ,'Missing') as varchar(10)) 

我所拥有的查询是为什么当我没有将varchar的数据类型转换为float(或者是我?)时为什么出现此错误

有人知道下一个地方去尝试解决此错误吗?

2 个答案:

答案 0 :(得分:1)

STR() function接受一个float数据类型作为第一个参数,因此SQL Server隐式转换了您传递给此函数的任何内容,在您的情况下,该函数就是CHAR(20)列。由于unknown无法转换为浮点数,因此会出现错误。 如果在启用实际执行计划的情况下运行以下命令:

DECLARE @T TABLE (Col CHAR(20));
INSERT @T VALUES (NULL);

SELECT Result = ISNULL(STR(Col, 25, 0), 'Missing')
FROM @T

然后检查执行计划XML,您将看到隐式转换:

<ScalarOperator ScalarString="isnull(str(CONVERT_IMPLICIT(float(53),[Col],0),(25),(0)),'Missing')">

最简单的解决方案可能是使用case表达式,而根本不打扰任何转换(仅当您知道仅列出的5个值时:

DECLARE @T TABLE (Col CHAR(20));
INSERT @T VALUES (NULL), ('0'), ('50'), ('100');--, ('Unknown');

SELECT Result = CASE WHEN Col IS NULL OR Col = 'Unknown' THEN 'Missing' ELSE Col END
FROM @T;

Result
---------
Missing
0                   
50                  
100                 
Missing             

如果您确实要使用STR()函数,则可以使转换显式,但可以使用TRY_CONVERT(),这样不是浮点数的任何内容都会简单地返回NULL

DECLARE @T TABLE (Col CHAR(20));
INSERT @T VALUES (NULL), ('0'), ('50'), ('100');--, ('Unknown');

SELECT Result = ISNULL(STR(TRY_CONVERT(FLOAT, Col), 25, 0), 'Missing')
FROM @T

Result
------------
Missing
        0   
       50
      100
Missing

尽管,由于您所说的数字是整数,所以我倾向于将它们转换为整数而不是浮点数:

DECLARE @T TABLE (Col CHAR(20));
INSERT @T VALUES (NULL), ('0'), ('50'), ('100'), ('Unknown');

SELECT Result = ISNULL(CONVERT(VARCHAR(10), TRY_CONVERT(INT, Col)), 'Missing')
FROM @T;

Result
---------
Missing
0                   
50                  
100                 
Missing      

答案 1 :(得分:0)

感谢@GarethD

我只遇到过TRY_CONVERT,这似乎是更好的选择,所以感谢他提供的指针,也尝试使用TRY_CAST。

数据确实应该保存在varchar字段中,它是参考而不是用于计算,这似乎同样有效,

-- Declare @varText as varchar(16) = '10    '
-- Declare @varText as char(16) = 'Unknown'
-- Declare @varText as char(16) = ''

SELECT
ISNULL(NULLIF(TRY_CAST(LTRIM(RTRIM(@varText)) as varchar(16)), ''), 'Missing') AS HESA

我已经创建了可以正常工作的测试方案。