我正在使用 OdbcDataReader
连接到 Oracle 数据库。在那里我有一个表,其中一个字段声明为 NUMBER(8, 2)。我在其中插入了值为“8.23”的行。使用 SELECT * FROM <table>
时显示正确在 SqlDeveloper 中。
但是,当使用 OdbcDataReader.GetDecimal() 从 .NET 通过 ODBC 访问此字段时,我得到一个 Decimal
包含“823”。这是为什么,我如何获得正确的值?
编辑:
如果我改为使用 OracleConnection
/OracleCommand
一切都按预期工作。
事实证明,如果我在我的 ODBC 驱动程序配置中将“数字设置”从“使用 Oracle NLS 设置”更改为“使用美国设置”,小数点也会正确返回。这到底是怎么回事?
基本上我使用下面的代码:
using (OdbcCommand command = new OdbcCommand("SELECT * FROM TEST", connection))
{
using (DbDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
Console.WriteLine(reader.GetValue(0));
}
}
}
这会打印出:
823
823
但正在运行 SELECT * FROM TEST
在 Oracle SQL Developer 中返回:
FLDNUM82
----------
8.23
8.23
并运行 desc TEST
返回:
Name Null Type
-------- ---- -----------
FLDNUM82 NUMBER(8,2)
最佳答案
经过一些调查并查看 source code OdbcDataReader
我发现在内部从 ODBC 源检索 decimal 类型的值时,它实际上从 ODBC 提供程序获取它作为字符串,然后尝试使用不变量将其解析为 decimal文化,如上面链接中的评论所示:
// internal GetDecimal
// -------------------
// Get Value of type SQL_DECIMAL or SQL_NUMERIC
// Due to provider incompatibilities with SQL_DECIMAL or SQL_NUMERIC types we always read the value
// as SQL_C_WCHAR and convert it back to the Decimal data type
这意味着,如果数据提供者发送的字符串中的小数点格式不同于不变区域性指定的格式,则转换将失败,或者更糟的是,产生不正确的结果。在我的例子中,小数点可能作为逗号字符发回,在美国文化中它是一个千位分隔符,这意味着它在调用 Decimal.TryParse
时被忽略了。
我不确定 OdbcDataReader
的作者选择的解决方案在这里是最好的,但可能存在我不知道的格式问题。不幸的是,除了完全远离 ODBC 之外,似乎没有解决此问题的好方法。
关于.net - 连接到 Oracle 数据源时,OdbcDataReader 会去除小数点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20492850/