【问题标题】:"Specified cast is not valid" when populating DataTable from OracleDataAdapter.Fill()从 OracleDataAdapter.Fill() 填充 DataTable 时“指定的转换无效”
【发布时间】:2014-07-19 02:22:39
【问题描述】:

我似乎在 Google(或 StackOverflow)上的任何地方都找不到这个问题,这真的让我感到惊讶,所以我把它放在这里是为了帮助处于同样情况的其他人。

我有一个在 Oracle Sql Developer 上运行良好的 SQL 查询,但是当我通过 C# 使用adapter.Fill(table) 运行它以获取结果时,我收到 Specified cast is not valid 错误 (System.InvalidCastException)。

这是 C# 代码的精简版:

var resultsTable = new DataTable();

using (var adapter = new OracleDataAdapter(cmd))
{
    var rows = adapter.Fill(resultsTable);  // exception thrown here, but sql runs fine on Sql Dev

    return resultsTable;
}

这里是 SQL 的简化版本:

SELECT acct_no, market_value/mv_total
FROM myTable
WHERE NVL(market_value, 0) != 0
AND NVL(mv_total, 0) != 0

如果我删除除法子句,它不会出错 - 所以它是特定的。但是,market_value 和mv_total 都是 Number(19,4) 类型,我可以看到 Oracle 适配器需要一个小数,那么发生了什么转换?为什么它在 SqlDev 上有效,而在 C# 中无效?

【问题讨论】:

    标签: c# oracle casting datatable decimal


    【解决方案1】:

    回答我自己的问题:

    因此,Oracle 数字类型似乎比 C# 十进制类型可以容纳更多的小数位,如果 Oracle 尝试返回的数量超过 C# 可以容纳的数量,它会抛出 InvalidCastException。

    解决方案?

    在您的 sql 中,将任何可能有太多小数位的结果四舍五入到合理的值。所以我这样做了:

    SELECT acct_no, ROUND(market_value/mv_total, 8)  -- rounding this division solves the problem
    FROM myTable
    WHERE NVL(market_value, 0) != 0
    AND NVL(mv_total, 0) != 0
    

    它奏效了。

    要点是:Oracle 数字类型和 C# 十进制之间不兼容。限制您的 Oracle 小数位以避免无效转换异常。

    希望这对其他人有帮助!

    【讨论】:

    • 感谢您为自己的问题发布解决方案。可能为我节省了几个小时(还有白发^^)。但是有没有办法避免在查询中四舍五入?
    • 我知道这篇文章有点老了,但这只是发生在我身上,四舍五入没有帮助。就我而言,我有一些非常高的价值观。为了完整性(希望市场价值不需要:-))写:ROUND(GREATEST(LEAST(market_value/mv_total,7.9E28),-7.9E28),8)
    • 你兄弟拯救了我的一天
    • 你用这个救了我的命。谢谢!
    • 虽然我没有遵循这个修正。我向你张贴它表示敬意。我在圈子里跑了几个小时。
    【解决方案2】:

    我知道这个帖子真的很老了。但是我遇到了类似的问题。

    我必须在 Oracle 十进制列上使用 Oracle 方法 TO_BINARY_DOUBLE 的最佳解决方案

    【讨论】:

      【解决方案3】:

      我知道这个问题已经得到解答,但我也找到了另一种我使用的替代方法。我在给我带来麻烦的领域使用了 CAST。

      基于 OP 的 SELECT 命令:

      SELECT acct_no, CAST((market_value/mv_total) AS DECIMAL(14,4))  -- CAST to decimal here
      FROM myTable
      WHERE NVL(market_value, 0) != 0
      AND NVL(mv_total, 0) != 0
      

      【讨论】:

        猜你喜欢
        • 2018-02-08
        • 2010-10-28
        • 1970-01-01
        • 2012-12-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-01-15
        • 1970-01-01
        相关资源
        最近更新 更多