C# &引用;指定的强制转换无效";从OracleDataAdapter.Fill()填充数据表时

C# &引用;指定的强制转换无效";从OracleDataAdapter.Fill()填充数据表时,c#,oracle,casting,datatable,decimal,C#,Oracle,Casting,Datatable,Decimal,我在Google(或StackOverflow)上找不到这个问题,这让我很惊讶,所以我把它放在这里是为了帮助其他处于同样情况的人 我有一个SQL查询,它在Oracle SQL Developer上运行得很好,但是当我使用adapter.Fill(table)通过C#运行它时,为了得到结果,我得到指定的强制转换无效错误(System.InvalidCastException) 下面是C代码的简化版本: 下面是SQL的简化版本: SELECT acct_no, market_value/mv_tot

我在Google(或StackOverflow)上找不到这个问题,这让我很惊讶,所以我把它放在这里是为了帮助其他处于同样情况的人

我有一个SQL查询,它在Oracle SQL Developer上运行得很好,但是当我使用
adapter.Fill(table)
通过
C#
运行它时,为了得到结果,我得到
指定的强制转换无效
错误(
System.InvalidCastException

下面是C代码的简化版本:

下面是SQL的简化版本:

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

如果我删除division子句,它不会出错——因此它是特定于此的。然而,market_value和mv_total都是数字类型(19,4),我可以看到Oracle适配器需要一个小数,那么进行什么转换呢?为什么它可以在SqlDev上工作而不能在C#中工作?

回答我自己的问题:

因此,似乎Oracle数字类型可以比C#decimal类型保留更多的小数位数,如果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#decimal之间不兼容。限制Oracle小数位数以避免无效强制转换异常


希望这对其他人有帮助

我知道这根线真的很旧了。。然而,我有一个类似的问题


我必须使用Oracle方法对Oracle十进制列进行二进制双精度运算的最佳解决方案

我知道这已经得到了回答,但我也找到了另一个我使用的替代方法。我在球场上使用了石膏,这给我带来了麻烦

根据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

感谢您为自己的问题发布解决方案。可能帮我省了几个小时(还有白发^^^)。但是有没有一种方法可以避免在查询中对数字进行舍入呢?我知道这篇文章有点老了,但这只是发生在我身上,舍入没有任何帮助。就我而言,我有一些非常高的价值观。为了完整(希望市场价值不需要:-)写:ROUND(最大(最小(市场价值/mv_总数,7.9E28),-7.9E28),8)你兄弟救了我的命你用这个救了我的命。谢谢虽然我没有按照这个固定。我向你致敬,谢谢你把它寄出去。我绕圈子跑了好几个小时。
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