我正在使用ADO将记录添加到MySQL表中。代码工作正常,数据发布到新记录,除了userid
以外。我无法弄清楚原因。
'---------------------------------------------------------------------------------------
' Procedure : IPhpList_AddHistory
' Author : Adam
' Date : 12/8/2014
' Purpose : Add a history record to the phpList account.
'---------------------------------------------------------------------------------------
'
Private Sub IPhpList_AddHistory(cUser As clsUser, cHistory As clsHistory)
Dim strSQL As String
Dim rst As ADODB.Recordset
Set rst = New ADODB.Recordset
strSQL = "phplist_user_user_history limit 0,1"
rst.Open strSQL, oConn, adOpenDynamic, adLockOptimistic
With rst
.AddNew
!userid = cUser.PhpListID
!ip = ""
![Date] = cHistory.AddDate
!Summary = cHistory.Subject
!Detail = cHistory.Body
!systeminfo = "Automated syncronization process. " & VBE.ActiveVBProject.Description
.Update
.Close
End With
' Clear reference
Set rst = Nothing
End Sub
看起来很简单,但MySQL中的结果记录缺少userid
值。
列上有一个索引,但似乎不应该阻止我设置该值。 (不,这张桌子上没有触发器。)
当我单步执行代码时,我可以看到该字段的值已设置,并且更新记录时没有错误,但在添加记录时它只是恢复为零。
我意识到我可以使用.Execute(strSQL)
添加记录,但我想了解为什么ADO代码难以为此列设置值。
进一步感兴趣的是,当我回去尝试更新现有记录上的userid列时,我得到了类似的结果。我设置了值,它恢复为零(或之前的任何值)。
现在这变得非常令人困惑......我在表中添加了另一个具有相同数据类型,长度等的列,突然代码按预期工作。我可以修改新列 和/或 userid
列中的值。 (并独立编辑值)
但是当我删除测试列时,它会回到之前的行为,不允许我更改userid
中的值。 (为什么会这样?)
更进一步,我在本地MySQL实例上创建了表,因此我可以在ADO查询到达数据库时对其进行概要分析。这揭示了一些非常有趣的行为。以下两个语句由相同的ADO代码生成,但第二个语句将测试列添加到表中。
INSERT INTO `test`.`phplist_user_user_history`(`id`,`userid`,`ip`,`date`,`summary`,`detail`,`systeminfo`)
VALUES (DEFAULT,DEFAULT,'',_binary'2014-12-18 11:51:13','My Subject','New Details','IBLP automated syncronization process. Version 1.0')
INSERT INTO `test`.`phplist_user_user_history`(`id`,`userid`,`ip`,`date`,`summary`,`detail`,`systeminfo`,`testcol`)
VALUES (DEFAULT,456,'',_binary'2014-12-18 13:22:44','My Subject','New Details','IBLP automated syncronization process. Version 1.0',1)
注意第一个insert语句如何输入DEFAULT
而不是我通过ADO传递的值。
第二个调用代码是相同的,只是它在testcol
中设置了一个值。当有两个INT(11)
列而不是一列时,为什么会以不同的方式运行?
进一步的线索是,当我在测试数据库中对表运行代码时,我在VBA中收到以下错误(即使我明确设置了userid值):
添加测试列后,错误会弹出测试列。在测试列上显式设置值后,.Update
成功,两个字段都正确更新。
这可能是ODBC驱动程序中的错误吗?我正在使用最新的MySQL ODBC连接器驱动程序(5.3.4)和以下连接字符串:
"Driver=MySQL ODBC 5.3 Unicode Driver;SERVER=myserver;UID=myuser;PWD={mysecretpwd};DATABASE=test;PORT=3306;DFLT_BIGINT_BIND_STR=1"
答案 0 :(得分:3)
我能够使用64位版本的MySQL ODBC 5.3 Unicode驱动程序(5.03.04.00)重新创建您的问题。当表中的最后一列是TEXT
类型时,它似乎是ADO Recordset更新的问题。我甚至没有userid
的索引,我得到了相同的结果。
一种可能的解决方法是使用带参数的ADODB.Command
来使用与此类似的代码执行插入:
Dim oConn As ADODB.Connection
Dim cmd As ADODB.Command
Set oConn = New ADODB.Connection
oConn.Open _
"Driver=MySQL ODBC 5.3 Unicode Driver;" & _
"SERVER=localhost;" & _
"UID=root;" & _
"PWD=whatever;" & _
"DATABASE=mydb;" & _
"PORT=3306;" & _
"DFLT_BIGINT_BIND_STR=1"
Set cmd = New ADODB.Command
cmd.ActiveConnection = oConn
cmd.CommandText = _
"INSERT INTO phplist_user_user_history " & _
"(`userid`, `ip`, `date`, `Summary`, `Detail`, `systeminfo`) " & _
"VALUES (?,?,?,?,?,?)"
cmd.Parameters.Append cmd.CreateParameter("?", adInteger, adParamInput, , 456)
cmd.Parameters.Append cmd.CreateParameter("?", adVarWChar, adParamInput, 255, "")
cmd.Parameters.Append cmd.CreateParameter("?", adDBTimeStamp, adParamInput, 255, Now)
cmd.Parameters.Append cmd.CreateParameter("?", adVarWChar, adParamInput, 255, "cHistory.Subject")
cmd.Parameters.Append cmd.CreateParameter("?", adLongVarWChar, adParamInput, 2147483647, "cHistory.Body")
cmd.Parameters.Append cmd.CreateParameter("?", adLongVarWChar, adParamInput, 2147483647, "Automated syncronization process.")
cmd.Execute
Set cmd = Nothing
oConn.Close
Set oConn = Nothing
我是从Access 2010数据库测试的,它对我来说很好。
答案 1 :(得分:0)
我可能错了,但似乎ADO期望桌子生成密钥,所以尽管它保持'你把它保存到数据库,它只是用它作为占位符。由于表格没有生成密钥,因此默认为0。
ADO中IPhpList_AddHistory的数据定义是否将AutoIncrement属性设置为true?如果是这样,它应该是假的。
答案 2 :(得分:0)
您是否验证过数据的格式是否正确?如果我没记错的话Access会看起来像文本数据类型一样工作到数字字段但是无法正常工作。