VARCHAR到数字转换,科学计数法引起转换错误-需要建议

时间:2019-05-14 21:33:30

标签: sql sql-server database

我之前有一个类似的话题,但已经演变成一个棘手的问题,我认为这没有真正的解决方案。希望我错了,但是要点在这里。

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

通过转换SQL过程-我将数据从varchar强制转换或转换为数字或十进制。当我这样做时,我会在某些值上出现错误。使用try_cast查询-我可以了解为何无法转换或转换为数字或十进制的罪魁祸首。

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

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

请参见下面的代码

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,因为这是一个自动过程)转换为数字或十进制。

如果我将文件加载到具有适当数据类型的表中,它甚至可以接受科学计数值吗?

1 个答案:

答案 0 :(得分:0)

指数表示法对于字符串到数字的转换无效。请考虑以下内容:

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。