14

我正在使用 c# .net 2 (Visual Studio 2005 SP1) 尝试使用来自 Oracle10g 数据库中的 select * from 表的结果填充数据集。无法在此客户端站点更改.net 框架、IDE 和数据库。

我正在使用ODP.net 提供程序连接,dll 版本是2.102.2.20

当我运行填充命令时,我得到一个异常:

算术运算导致溢出

此外,如果我尝试在 Visual Studio 设计器(显示表数据)中查看有问题的列,我会得到对于表中该列的每一行。如果我的查询选择其他具有整数的列,例如省略此列,则该代码将完美运行。

当我从 Toad 在数据库中查看有问题的列时,它看起来很好,数据如下所示:

919.742866695572

我需要精度,因为它是蒙特卡罗模拟所需的。

如果我不使用数据适配器来填充数据表,而是使用数据读取器并调用 dataReader.getValue(columnIndex) 我会得到相同的错误,但是如果我调用 dataReader.GetOracleDecimal(columnIndex) 那么我会得到我正在寻找的结果,没有错误.

我宁愿使用数据适配器并填充数据集(注意这些是无类型数据集,因为我无法从 oracle db 中获取自动生成的强类型数据集)。我不想使用 datareader 并遍历结果(选择列值),因为我试图将其编写为适用于许多场景的通用方法,无论列数如何,十进制列的索引需要特定按数据类型获取调用。

任何人都可以帮忙吗?我可以使用新版本的 ODP.net dll 连接到旧的Oracle10g数据库吗?我想知道这是否会有所帮助。

谢谢

4

3 回答 3

1

The problem is that the precision of the result value is too high to convert to a System.Decimal without some data loss. I forget the exact number of digits allowed, but it is around 18 or so. Is it acceptable to round() the result value to that many digits? In the example you gave, a round(MyColumn, 15) or so should be sufficient...

于 2010-11-26T04:30:52.803 回答
0

您可以尝试最新版本的 ODP.Net (11g)。它向后兼容。我用它来连接一个10g的数据库就好了。我认为它也应该适用于 VS 2005。对于 clickonce 部署,只需添加此问题引用的 dll:将 C# 连接到 Oracle 数据库所需的最小客户端占用空间是多少? 重要的一点是,如果您拥有最新版本的 odp.net,则所有 dll 都包含在安装目录中。您无需单独下载即时客户端。只需搜索它们。

于 2009-06-25T14:14:00.510 回答
0

如果您迁移到更高版本的 ODP.NET(如 12.x),则错误只会从“算术溢出”更改为“无效转换异常”。您必须 CAST 数值来减少疯狂的精度值,如 29 或 30 位小数,使其更实用,如 2 到 4 位小数。

要识别具有过大十进制值的列和行,您可以在将 MY_SCHEMA、MY_TABLE 和数字 10 替换为 25 后运行下面的 SQL 来识别值超过 25 位小数的列。此 SQL 将生成一个 SQL,应运行该 SQL 来识别问题列。

SELECT 'SELECT ' || LISTAGG('MAX(LENGTH(TO_CHAR(ABS(' || column_name || ') - FLOOR(ABS(' || column_name || '))))) - 1  AS decimals_' || column_name || CHR(13)
                    , CHR(9)|| ', ') WITHIN GROUP (ORDER BY rn)  ||
                    ' FROM ' || owner || '.' || table_name  || CHR(13) ||
                    ' WHERE '  || CHR(13) ||
                      LISTAGG('(LENGTH(TO_CHAR(ABS(' || column_name || ') - FLOOR(ABS(' || column_name || ')))) - 1) > 10 ' || CHR(13)
                                , CHR(9)|| '  OR  ')
WITHIN GROUP (ORDER BY rn) AS Nasty_Numbers_Finder_Query
FROM
(
    SELECT  owner, table_name, column_name,
        row_number() OVER ( PARTITION BY table_name  ORDER BY rownum) rn
    FROM  dba_tab_columns
    WHERE
        OWNER = 'MY_SCHEMA'
        AND table_name = 'MY_TABLE'
        AND (data_type LIKE '%FLOAT%'
            OR data_type LIKE '%NUMERIC%')
) a
GROUP BY owner, table_name

欲了解更多信息,我已在此处发表博客。

于 2020-02-20T20:39:52.623 回答