从 OracleDataAdapter.Fill() 填充 DataTable 时“指定的转换无效”

Posted

技术标签:

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

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

我有一个在 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# 中无效?

【问题讨论】:

【参考方案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

【讨论】:

以上是关于从 OracleDataAdapter.Fill() 填充 DataTable 时“指定的转换无效”的主要内容,如果未能解决你的问题,请参考以下文章

OracleDataAdapter Fill 方法挂起

c# OracleDataAdapter.Fill 遇到不支持的 Oracle 数据类型

在 oracle sql developer 中加入查询快,在 odp.net 中超慢

从 NIB 与从代码加载自定义滑块:从代码加载时不存在子视图

如何从其他面板从 JTextField 获取输入

从PRISM开始学WPFMVVMViewModel?