c++ - 将数据从数据库正确加载到编辑控件中,以便我可以执行 ADO 查询

标签 c++ winapi ms-access-2007 locale ado

简介和相关信息:

我有一个 MS Access 2007 数据库,其中有一个包含 string 字段和 numerical 字段的表。 numerical 字段的类型为 double,可以为负值或正值。

我使用 ADO 连接到数据库,并使用 edit API 将其数据加载到 SetDialogItemText 控件中 - edit 控件位于 dialog box 中。

用户可以编辑现有数据的值(保存更改时,我使用 edit API 从 GetDialogItemText 控件获取数据)。

问题:

如果用户使用英语或美国语言环境,我的程序一切正常,但如果用户选择欧洲语言环境,则我的 ADO string 不正确并报告错误。

这是预期的,因为在英语版本中它有 2 个参数 - stringdouble 但由于欧洲人使用逗号作为小数点(例如美国 123.456123,456 )ADO 将其解释为 < strong>3 个参数而不是两个 - 例如:

INSERT INTO table VALUES ( 'some string', 12.5 ); ---> 美国语言环境

INSERT INTO table VALUES ( 'some string', 12,5 ); ---> 错误! 3个参数代替2个

更彻底地解释:

假设我们已使用欧洲语言环境将数据从数据库加载到编辑控件中:

第一个包含 string ( Some string ),第二个包含一个十进制数 ( 123,456 )。

假设用户将 string 值更改为 Some other string 并按下保存按钮。

现在我的代码从 edit 控件获取值,但由于我从第二个编辑控件获取 123,456 (记住,用户保留十进制数据不变),所以一定会发生错误,并且我的 ADO string 未正确配置,因为现在看起来像这样:

INSERT INTO table VALUES ( 'Some other string', 123,456 ); --> 错误! 3个参数

我的问题:

如果用户设置了欧洲语言环境,是否有办法将 MS Access 2007 数据库中的十进制值加载到编辑控件中,并将逗号已更改转换为点?

或者也许我可以以某种方式 subclass edit control 将逗号更改为点?

sublclassing 控件可以将用户输入限制为点和字母,因此这不是问题。我只想正确地从数据库加载数据,因此如果用户决定不编辑十进制数据(就像我上面描述的示例中那样),我的 edit 可以无错误地执行。

谢谢。

最诚挚的问候。

最佳答案

这里有两个问题。我将使用两种语言环境进行说明:

英语(加拿大)--EN-CA:使用 . 作为小数点分隔符
法语(加拿大)——FR-CA:使用 , 作为小数点分隔符

还有一小段 VBScript 代码(因为我没有 C++)。

问题 1:十进制数与区域设置感知字符串之间的转换。

VBScript

x = 3/2
WScript.Echo x

当 Windows 区域设置为 EN-CA 时显示 1.5,当 Windows 区域设置为 FR-CA 时显示 1,5。该文本就是您在编辑框中看到的内容。

假设用户保持字符串不变。您不需要尝试使用十进制数的字符串表示形式,而是需要使用区域设置感知方法将字符串转换回实际的十进制数:

对于 EN-CA:

x = CDbl("1.5") + 1
WScript.Echo x

显示2.5,表示字符串“1.5”在添加 1 之前已成功转换为 Double

对于 FR-CA:

x = CDbl("1,5") + 1
WScript.Echo x

显示 2,5 表示字符串“1,5”在添加 1 之前已成功转换为 Double

摘要:当您从用户处收到数字的文本表示形式时,您需要将该字符串转换(即解析)为实际的数字数据类型,并且解析机制必须能够识别区域设置。

问题 2:将号码存储在数据库中。

这里的问题是 Access SQL 不支持区域设置;它只“说”美国英语。因此,如果您尝试在 FR-CA 下“粘合”一条 SQL 命令

x = 3/2
sql = "INSERT INTO Table1 (DoubleField) VALUES (" & x & ")"
WScript.Echo sql

您得到INSERT INTO Table1 (DoubleField) VALUES (1,5),但正如您所发现的那样,失败了。

这里的解决方案是不要将 SQL 命令“粘合在一起”(无论如何,这都是一件坏事,因为 SQL 注入(inject)漏洞和其他麻烦)。相反,使用参数化查询:

Option Explicit
Dim con  ' ADODB.Connection
Dim cmd  ' ADODB.Command
Dim prm  ' ADODB.Parameter
Dim x
Const adDouble = 5
Const adParamInput = 1

' test data:
'     the following statement is valid when 
'         the Windows locale uses "," as the decimal separator
x = CDbl("1,5")

Set con = CreateObject("ADODB.Connection")
con.Open _
        "Driver={Microsoft Access Driver (*.mdb, *.accdb)};" & _
        "Dbq=C:\__tmp\main.accdb;"
Set cmd = CreateObject("ADODB.Command")
cmd.ActiveConnection = con
cmd.CommandText = "INSERT INTO Table1 (DoubleField) VALUES (?)"
Set prm = cmd.CreateParameter("?", adDouble, adParamInput, , x)
cmd.Parameters.Append prm
cmd.Execute
Set prm = Nothing
Set cmd = Nothing
con.Close
Set con = Nothing

关于c++ - 将数据从数据库正确加载到编辑控件中,以便我可以执行 ADO 查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21395499/

相关文章:

c++ - unordered_map对哈希函数的多余调用

c++ - WritePrivateProfileString 没有在末尾添加属性

c# - 是否可以获取和修改文本框的标准系统上下文菜单?

SQL 将重复项提取到 Access 中的新表中

c++ - 在cygwin上编译Boost asio出现很多错误

c++ - std::list 迭代器没有被分配

C++使用For循环创建双向链表

c++ - 如何 CloseHandle 转换为 FILE* 的句柄?

sql - MS_Access 中单个查询中的多个操作

vba - Access 2007 VBA DoCmd.Close 不工作