c# - 从 OracleDataAdapter.Fill() 填充 DataTable 时为 "Specified cast is not valid"

标签 c# oracle casting datatable decimal

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

我有一个在 Oracle Sql Developer 上运行良好的 SQL 查询,但是当我使用 adapter.Fill(table) 通过 C# 运行它以获取结果时,我得到 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# 中无效?

最佳答案

回答我自己的问题:

所以看起来 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 小数位以避免无效转换异常。

希望这对其他人有帮助!

关于c# - 从 OracleDataAdapter.Fill() 填充 DataTable 时为 "Specified cast is not valid",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23935716/

相关文章:

c# - 分配和方法调用顺序

oracle - 使用 if 语句 PL/SQL 更新表

c++ - 移位 `char` 与 `unsigned char`

c# - Windows 窗体 : Pass clicks through a partially transparent always-on-top window

c# - 信用卡付款方式

c# - 使用 TLSharp 通过 Telegram 使用 C# 发送消息

oracle - 为什么 Oracle 接受字符串值前的加号 (+)?

sql - SQL Server 中的 DECODE() 函数

java - 转换代理 - 获取 ClassCastException

java - 将类转换为不相关的接口(interface)