DataReader 在读取 Oracle 中两个长小数点除法的结果时抛出'Specified cast not valid'



我在VB中有以下示例。. NET 4.0, VS2010, Oracle 10g)

Dim objDb As New OracleOdp("my_connection_info.udl")
        Dim sql = <sql>
            SELECT 'okay' As PoC, TO_NUMBER('47,3222404188609999999999999999999999') / TO_NUMBER('21,3222404188609999') FROM dual
        </sql>.Value
        objDb.SQL = sql
        Dim dr = objDb.Execute()
        dr.Read()
        Console.WriteLine(String.Format("Field count: {0}", dr.FieldCount))
        Console.WriteLine(String.Format("First value (= 'okay'): {0}", dr(0)))
        Console.WriteLine(String.Format("Second value (throws cast error): {0}", dr(1)))

OracleOdp是一个自定义类,用来创建一个简单的Oracle连接。

在执行这个示例时,当我试图读取我的DataReader的第二列中的内容时,我在最后一行得到一个错误,说"指定的强制转换无效",并使用以下堆栈跟踪(来源:Oracle.DataAccess):

   à Oracle.DataAccess.Client.OracleDataReader.GetDecimal(Int32 i)
   à Oracle.DataAccess.Client.OracleDataReader.GetValue(Int32 i)
   à Oracle.DataAccess.Client.OracleDataReader.get_Item(Int32 i)
   à HelpPls.Module1.Main() dans C:UsersxxxxDocumentsTempHelpHelpPlsModule1.vb:ligne 24
   à System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
   à Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
   à System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   à System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   à System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   à System.Threading.ThreadHelper.ThreadStart()

我被迫使用Oracle。数据访问DLL版本4.112.2.0.

每次我尝试将小数除以另一个小数时都会发生错误,但是我不可能截断或四舍五入数字,因为它们在其他地方使用(注意,不是在VB中!)在条件。

如何让它工作?

您通常使用的方法是使用OracleDecimal数据类型。我很抱歉我不懂VB.net,但为了演示这一点,这里有一个简单的c#示例:

OracleCommand cmd = new OracleCommand(<your query>, conn);
OracleDataReader reader = cmd.ExecuteReader();
reader.Read();
OracleDecimal d1 = reader.GetOracleDecimal(1);

从这里,您可以简单地通过:

获得十进制值:
decimal d2 = d1.Value;

或者更简洁地说,两个语句合二为一:

decimal d = reader.GetOracleDecimal(1).Value;

尽管如此,结果的精度对于小数来说太高了,这会抛出一个错误。你真的需要双精度才能使它工作。以下任何一种方法都应该适合您:

double d = reader.GetOracleDecimal(1).ToDouble();

或者更好,因为这样不会失去精度

double d = reader.GetDouble(1);

这就是@jmcilhinney在他的评论中所说的。

最新更新