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

时间:2014-01-28 02:03:08

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

引言及相关资料:

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

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

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

问题:

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

这是预期的,因为在英文版本中它有2个参数 - stringdouble,但由于欧洲人使用逗号作为小数点(例如US {{ 1}}是123.456123,456将其解释为具有 3个参数而不是两个 - 例如:

ADO ---&gt;美国语言环境

INSERT INTO table VALUES ( 'some string', 12.5 ); ---&gt;错误! 3个参数代替2

更彻底地解释:

我们假设我们已使用欧洲区域设置将数据从数据库加载到编辑控件中:

第一个持有INSERT INTO table VALUES ( 'some string', 12,5 );string)和第二个十进制数(Some string)。

我们假设用户将123,456值更改为string,然后按保存按钮。

现在我的代码从Some other string控件获取值,但错误必须发生,因为我从第二个编辑控件{记住,用户左侧小数数据未更改得到edit,我的123,456配置不正确,因为它现在看起来像这样:

ADO string - &GT; ERROR! 3个参数

我的问题:

如果用户设置了欧洲语言环境,是否可以将INSERT INTO table VALUES ( 'Some other string', 123,456 );数据库中的十进制值加载到编辑控件中,逗号已更改为点?

或者我可以以某种方式MS Access 2007将逗号更改为dot?

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

谢谢。

祝你好运。

1 个答案:

答案 0 :(得分:2)

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

英语(加拿大) - 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之前,字符串“1.5”已成功转换为Double

对于FR-CA:

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

显示2,5,表示在添加1之前,字符串“1,5”已成功转换为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注入漏洞和其他麻烦)。而是使用参数化查询

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