哪个是语言环境感知的:OleDb.Currency或OleDb.Decimal?

时间:2009-07-24 18:00:23

标签: ado.net localization oledb ado

这是双重的。我有一个Access数据库和一个包含MS Access Currency字段的表。我在美国的客户使用十进制值,如1.23,我在厄瓜多尔的客户使用十进制值,如1,23。

我有一些ADO遗留代码,我尝试创建类型为adDecimal且类型为adCurrency的ADODB参数。在任何一种情况下,执行我的ADODB命令后,Access中的数据为美国的1.23(预期)和厄瓜多尔的123.00(未预期)。

在我的.NET代码中,我尝试使用类型为OleDb.Currency和OleDb.Decimal的OleDb参数。似乎OleDb.Currency是区域设置感知的,但OleDb.Decimal不是。

我的头在旋转。有没有人知道我的遗留代码对国际货币的正确ADO使用情况,以及在我们的代码库向前推进时编写.NET参数的正确方法?

谢谢!

4 个答案:

答案 0 :(得分:0)

好的,经过一些额外的挖掘后,似乎“货币”类型优于“十进制”类型。换句话说,对ADO或OleDb.Currency使用adCurrency将对保存到MS Access货币字段的十进制值起作用。

为了防止其他人出现 - 我确实在ADO案例中发现了一个非常奇怪的行为,如下所示:

我的代码实例化了一个新的ADODB命令并设置了Parameters集合 - 包括一些键入的adCurrency。然后,我开始更新数据库中的几条记录。我为每次更新重用了相同的命令对象,并调用了一个方法,在下一个更新块启动之前将所有参数字段重置为0。这导致我的字段中的数据不正确(请参阅上面描述的初始问题)。我尝试了很多东西来解决这个问题并且没有成功。我甚至注释掉了对我的ResetParameters方法的调用,以确保行为不相关。

修复:我最终决定在每个更新块之前新建一个全新的命令对象,而不是重用命令对象。突然,无论我的语言环境设置如何,我的所有十进制值都以正确的方式显示在Access中。

总之,在调用Execute方法后,我的命令对象上出现了一些修改,以致后续更新中的adCurrency参数被破坏。顺便说一句,结果如下:一个4,32值将出现在Access中为432(这是厄瓜多尔货币格式)。我的代码并不是非常复杂,我不会在这里发布,但有两个人非常努力地看着这个,我们只是没有看到任何可以解释它的东西。事实上,创建一个新实例的想法是在我们编写一个测试应用程序的时候出现的,该测试应用程序只调用了一个更新,而且测试中的完全相同的代码就像预期的那样。

如果您正在编写本地化应用程序,请注意重用ADO命令对象以进行多次更新。

答案 1 :(得分:0)

内部类型不支持区域设置,它们只是数字 当您从输入中捕获它们并将它们显示到窗口或报告时,语言环境会产生影响。

答案 2 :(得分:0)

@Eduardo, 我理解您对格式化的看法。在这种情况下,我根本不向UI或任何输出显示数据。当我完全从代码发出数据库更新时,我遇到了意外的行为。

我真的不熟悉Jet等提供程序(用于Access数据库)的低级别。命令参数是否会转换为稍后解析的实际SQL字符串,或者是以某种方式直接消耗的参数?我不确定。

我确信我所看到的行为表明提供者逻辑的作者区分“货币”和“十进制”类型,以便将数字参数插入到适当的MS Access类型中。当我们使用错误的参数类型时,内部会发生转换并导致结果混乱。

一个看似更常见的问题(更容易找到修复)是处理日期。再次以厄瓜多尔为例,该地区的日期格式为日/月/年,而不是美国的月/日/年。像这样的SQL字符串效果不好:

更新客户SET DateOfBirth =#03/06/1970#

SQL解析器将始终读取此日期为3月6日(去美国!)但在Ecudaor中它实际上意味着6月3日。解决此问题的方法是在将日期添加到SQL字符串之前始终将日期转换为普遍接受的格式:

更新客户SET DateOfBirth =#1970-06-03#(1970年6月3日)

围绕货币的“陷阱”有点微妙 - 而且我的ADO参数在循环迭代期间没有表现(参见上面接受的答案)的事实很奇怪。

答案 3 :(得分:0)

使用Double而不是Decimal来声明数据库MSAccess中列的类型。 它起作用,它独立于区域设置。