我似乎无法在 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/