VARCHAR 到数字转换,科学记数法导致转换错误 - 需要建议

Posted

技术标签:

【中文标题】VARCHAR 到数字转换,科学记数法导致转换错误 - 需要建议【英文标题】:VARCHAR to numeric conversion, scientific notation causing conversion error - advice needed 【发布时间】:2019-05-14 21:33:30 【问题描述】:

我之前有一个类似的线程已经演变成一个我可能认为没有真正解决方案的难题。希望我错了,但这是要点。

我将表中每个成员的数据类型定义为 Varchar(80)。然后,我使用将数据加载到表中的集成器工具将数据从外部系统 (Oracle PBCS) 加载到平面文件中。

通过转换 SQL 过程 - 我将数据从 varchar 转换或转换为数字或十进制。当我这样做时,我得到一些值的错误。使用 try_cast 查询 - 我可以看到为什么我不能转换或转换为数字或小数的罪魁祸首。

提取以科学记数法加载这些值 - 不知道为什么源系统完全这样做 - 所以我决定尝试在 SQL 中控制它 - 但不幸的是,没有任何工作,因为我必须先转换为浮点数转换为数字或十进制。对于非常小的值,例如 6.27e^-19 - 我的浮动只是将美分的分数减少到 0 - 通常浮动对于货币来说似乎是一个非常糟糕的主意。

如果我保留 try_cast,那么我将返回 null 值 - 我真的不能这样做。

见下方代码

1.455191522836685e-11
1.455191522836685e-11
1.455191522836685e-11
1.455191522836685e-11
1.455191522836685e-11
1.455191522836685e-11
1.455191522836685e-11
1.455191522836685e-11
1.455191522836685e-11

这些是我通过 try_cast 解决的问题。

select 
   t.[acct_20010]
   --convert(numeric(19,4), convert(float, t.[acct_20010]))
  --cast( cast(t.[acct_20010] as float) as decimal(18,10))
  -- ,CAST([Obligated] AS FLOAT)  
  --  ,CAST([Total_Expended] AS FLOAT)     
              --  ,CAST([Total_Obligated_FAMIS] AS FLOAT)
    --,CAST([Spendplan_Balance] AS FLOAT)
    --,CAST([Pending_Expenditures] AS FLOAT)
     --           ,CAST([Unexpended_Balance] AS FLOAT)
    --,CAST([Funds_Remaining_by_BBFY] AS FLOAT)
    --,CAST([PY_Funds_Remaining] AS FLOAT)
--select t.[expended]
--from 
from
(select [acct_20010] as [acct_20010]
--,[obligated],
--Total_Expended
FROM [BFS_DM].[Source].[Cld_Ess_SpendPln] where ([acct_20010] is not null and [acct_20010] <> '#missing'))  t
where TRY_CAST(t.[acct_20010] AS NUMERIC(18,4)) IS NULL

我只需要一些关于如何将科学记数法值(不使用 excel,因为这是一个自动化过程)转换为数字或十进制的指导。

如果我将文件加载到具有正确数据类型的表中 - 它甚至会接受科学记数法值吗?

【问题讨论】:

您问题中的值可以很好地转换为浮点数 (dbfiddle.uk/…)。也许你在字符串中有一些看不见的字符。 嗨,戈登,感谢您的帮助!目前,出现并加载到表中的提取是字符串值。这些值中的大多数在 sql 选择中都可以很好地转换为数字 - 但由于“错误的指数表示法”条目,查询在转换为数字后永远不会返回结果。 我只是收到错误“无法将 varchar 转换为数字”。所以我使用 try_cast 来尝试找到在转换为 numeric(18,4) 时返回 null 的值——这意味着这些是错误的条目。所有这些都返回科学指数符号。不幸的是,当我 try_cast 或这些浮动然后数字时,我失去了 1.455191522836685e-11 变为 0.0000。即使我只是将数字转换为浮点数 - 1.455191522836685e-11 变为 1.45519152283669e-11。所以一般来说浮动是有问题的。但它似乎是指数级的——一切都失去了。 .0000000001455191522836685 - 是我想要的输出 【参考方案1】:

指数符号对字符串到数字的转换无效。考虑以下几点:

select try_cast('1.455191522836685e-11' AS numeric(18,4))
select try_cast('1.455191522836685e-1' AS numeric(18,4))
select try_cast('1.455191522836685' AS numeric(18,4))

只有最后一个有效,因为它没有明确的指数。

如果必须,您可以通过先转换为浮点数然后再转换为数字来解决此问题:

select try_cast(try_cast('1.455191522836685e-11' as float) AS numeric(18,4))
select try_cast(try_cast('1.455191522836685e-1' as float) AS numeric(18,4))
select try_cast(try_cast('1.455191522836685' as float) AS numeric(18,4))

不过,观察精度 - 您会注意到第一个示例的结果为 0。

【讨论】:

大家好,感谢 cmets。由于我有这些以指数形式表示的科学值 - 有没有办法可以筛选出指数,因为我发现一分钱的小数会减少到零。我需要按原样保留那一分钱。 请提供一些输入和期望输出的具体示例,我会看看是否可以提供帮助。 您好 BoCoKeith,感谢您的帮助!目前,出现并加载到表中的提取是字符串值。这些值中的大多数在 sql 选择中都可以很好地转换为数字 - 但由于“错误的指数表示法”条目,查询在转换为数字后永远不会返回结果。我只是收到错误“无法将 varchar 转换为数字”。 继续,所以我使用 try_cast 来尝试找到在转换为 numeric(18,4) 时返回 null 的值——这意味着这些是错误的条目。所有这些都返回科学指数符号。不幸的是,当我 try_cast 或这些浮动然后数字时,我失去了 1.455191522836685e-11 变为 0.0000。即使我只是将数字转换为浮点数 - 1.455191522836685e-11 变为 1.45519152283669e-11。所以一般来说浮动是有问题的。但它似乎是指数级的 - 就进入 .0000000001455191522836685 而言,一切都丢失了 1.455191522836685e-11 是 0.000000000014551915...,因此,自然地,转换为 4 位十进制值将产生 0.0000。你期待什么?

以上是关于VARCHAR 到数字转换,科学记数法导致转换错误 - 需要建议的主要内容,如果未能解决你的问题,请参考以下文章

在 SQL 中转换/转换科学记数法 [从 Varchar 到 Decimal/Numeric]

如何避免以科学记数法表示的双精度数和数字的字符串到数字转换?

MSSQL中 float转换为varchar 变成科学计数法解决方案

将数据帧转换为 numpy 数组会导致所有数字以科学计数法打印 [关闭]

将 varchar 转换为数字数据类型时出现算术溢出错误。找不到存储过程''。?

如何解决“将 varchar 数据类型转换为 datetime 数据类型导致值超出范围。”错误