通过 .Net 和 SqlBulkCopy 从 Oracle 到 SQL 服务器的高精度传输浮点数

Transport float with huge precision from Oracle to SQL Server via .Net and SqlBulkCopy

使用 ODP.Net 我连接到 Oracle 数据库并使用 SqlBulkCopy 将数据传输到 SQL 服务器。

正如我们大多数人已经注意到的那样 - Oracle 浮点数可以保存比 .Net 变量可以保存的精度更高的值。 .Net 可以保持高达 28 的精度,而 Oracle 可以有例如30. 在那种情况下,ODP.Net 与 "Specified cast is invalid" 崩溃。

Oracle 不会调整他们的代码,Microsoft 也不会创建精度更高的新变量,这让我们不得不采取变通办法。

在我的例子中,我找不到另一种方法,只能将 Oracle 浮点数转换为 nvarchar,然后将它们保存到 SQL 服务器临时 table 类型为 nvarchar,然后使用将该 nvarchar 转换为 SQL 服务器浮点数的存储过程。 这样我可以保留原始值并且不会丢失它的一部分精度。

甲骨文: 对于 SqlBulkCopy,我使用此 sql 从 Oracle 获取数据:

SELECT TO_CHAR(the_float) FROM the_table;

bulkCopy.WriteToServer(reader);

然后在 SQL 服务器上我看到了这个值,就像这样:

-,00000000000000088817841970012

这是 Oracle 的默认格式设置(缺少前导 0)。

转换使用 T-SQL

SELECT Try_convert(float,'-,00000000000000088817841970012') FloatValue

(我不得不用 . 替换 , 这样我的 SQL 服务器就会将其识别为浮点数并且转换有效!)

Try_convert(float,REPLACE('-,00000000000000088817841970012', ',', '.'))  FloatValue

这是解决我描述的 Oracle Float 和 .Net 变量(ODP.Net 和 .Net)不一致的方法吗?

在你使用的所有标签中,我对 Oracle 了解一点。也许您缺少带有 TO_CHAR 函数的格式掩码。这是一个例子:

SQL> create table the_table (the_float number);

Table created.

SQL> insert into the_table values (-0.00000000000000088817841970012);

1 row created.

SQL>
SQL> select to_char(the_float) your_result,
  2         to_char(the_float, '0D9999999999999999999999999999999999') my_result
  3  From the_table;

YOUR_RESULT                              MY_RESULT
---------------------------------------- -------------------------------------
-,00000000000000088817841970012          -0,0000000000000008881784197001200000

SQL>

看看是否有帮助(希望有帮助)。

更多关于格式模型的信息:https://docs.oracle.com/en/database/oracle/oracle-database/12.2/sqlrf/Format-Models.html#GUID-EAB212CF-C525-4ED8-9D3F-C76D08EEBC7A