在科学记数法十进制数表示含有许多错误铸造VARCHAR(Error casting varchar

2019-10-16 12:52发布

我目前工作的一个ETL项目中,从MongoDB的数据是越来越转换为关系型数据库和存储在SQL Server。 我遇到的问题是,一些在MongoDB中同场的数字存储为十进制(0.058823),有时用科学记数法(5.8823e-02)。

当我和Postgres的工作在这两种格式的数值得到了为双值过去了,我没有任何问题与两种格式的查询。 这似乎并不与SQL服务器的情况。

目前,所有的数据传递为varchar和我使用下面的代码同桌的看法:

CAST (CASE 
         WHEN [fieldname] LIKE '%e%' 
            THEN log([fieldname]) 
            ELSE [fieldname] 
      END AS DECIMAL(30, 20)) AS [FieldName1]

也有名单,我变成子和铸造这需要使用CTE的字段。 这是从转100+我的代码几乎600+线。 不知道是否有一个更简单的方法吗?

我真的很感谢所有帮助您可以提供。

Answer 1:

SQL Server支持科学记数法和“常规”小数。

这里有一个简单的例子:

DECLARE @D decimal(10, 6) = 0.058823,
        @S decimal(10, 6) = 5.8823e-02

SELECT  @D As Regular, 
        @S As Scientific, 
        IIF(@D = @S, 1, 0) As AreEqual

这个SELECT语句的结果是:

Regular     Scientific  AreEqual
0.058823    0.058823    1

然而 ,从铸造varchar与常规小数完美十进制工作,但提出了用科学记数法的错误:

DECLARE @SD varchar(10) = '0.058823',
        @SS varchar(10) = '5.8823e-02'                 

SELECT CAST(@SD AS decimal(10, 6)) As RegularString,
       CAST(@SS AS decimal(10, 6)) As ScientificString

提出这个错误:

误差数据类型为varchar转换为数字。

铸造浮动,而另一方面,完美的作品 - 所以要得到一个小数,你可以施放浮动,然后为十进制:

SELECT  CAST(@SD AS decimal(10, 6)) As RegularString,
        CAST(CAST(@SS AS float) AS decimal(10, 6)) As ScientificString

结果:

RegularString   ScientificString
0,058823        0,058823


Answer 2:

由于您主要关注的似乎是代码膨胀(600线与100),你可以创建一个功能

CREATE FUNCTION dbo.GetDecimal(@input VARCHAR(32))
RETURNS DECIMAL(30,20)
AS
BEGIN
    RETURN CAST(CAST(@input AS FLOAT) AS DECIMAL (30, 20)) 
END

并把它在你的每个字段的SELECT语句转换,就像这样:

SELECT 
  dbo.GetDecimal(sfield1) as tfield1,
  dbo.GetDecimal(sfield2) as tfield2,
  ...
FROM ...

注意:你的问题的第一条评论正确地指出,你不应该使用日志()函数。 相反,该用户函数执行的中间铸件的最终流延到小数点前浮动。 这是必要的,因为在科学记数法表示字符串值不能直接转换为十进制。



文章来源: Error casting varchar containing a number expressed in scientific notation to decimal