Indexed MySQL field not saving value when creating/editing record through ADO

与世无争的帅哥 提交于 2020-01-24 07:44:27

问题


I am using ADO to add a record to a MySQL table. The code works fine, and the data is posted to the new record, all except the userid. I can't figure out why.

'---------------------------------------------------------------------------------------
' 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

Seems simple enough, but the resulting record in MySQL is missing the userid value.

There is an index on the column, but it does not seem like this should prevent me from setting the value. (And no, there are no triggers on this table.)

When I step through the code, I can see that the value for this field is set, and there are no errors when the record is updated, but somehow it just reverts to zero when the record is added.

I realize that I can add the record using .Execute(strSQL), but I would like to understand why the ADO code is having difficulty setting a value for this column.

Of further interest, when I go back and try to update the userid column on an existing record, I have a similar result. I set the value, and it reverts back to zero (or whatever previous value was there).

Update

Now this is getting really perplexing... I added another column with the same data type, length, etc... to the table, and suddenly the code works as expected. I can edit the value in the new column and/or the userid column. (And edit the values independently)

But when I remove the test column, it goes back to the previous behavior, of not allowing me to change the value in userid. (why would this be??)

Taking things a step further, I created the table on a local MySQL instance so I could profile the ADO queries as they hit the database. This revealed some very interesting behavior. The following two statements were generated by the same ADO code, but the second one had the test column added to the table.

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)

Notice how the first insert statement inputs DEFAULT instead of the value I passed through ADO.

The second calling code was identical, except that it set a value in testcol. Why would this run differently when there are two INT(11) columns instead of one?

A further clue is that when I run the code against the table in my test database, I get the following error in VBA (even though I am explicitly setting the userid value):

After adding the test column, the error then pops up on the test column. After explicitly setting the value on the test column, the .Update is successful, and both fields are updated correctly.

Could this possibly be a bug in the ODBC driver? I am using the latest MySQL ODBC connector driver (5.3.4), and the following connection string:

"Driver=MySQL ODBC 5.3 Unicode Driver;SERVER=myserver;UID=myuser;PWD={mysecretpwd};DATABASE=test;PORT=3306;DFLT_BIGINT_BIND_STR=1"

回答1:


I was able to recreate your issue with the 64-bit version of the MySQL ODBC 5.3 Unicode Driver (5.03.04.00). It appears to be an issue with ADO Recordset updates when the last column in the table is of type TEXT. I did not even have an index on userid and I got the same results.

One possible workaround would be to use an ADODB.Command with parameters to perform the insert using code similar to this:

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

I tested it from an Access 2010 database and it worked fine for me.




回答2:


I could be wrong but it appears that the ADO is expecting the table to generate the key, so while it 'keeps' your keep around until it sends it to the database, it is only using it as a place holder. And since the table isn't generating the key it defaults to 0.

Does the data definition for the IPhpList_AddHistory in the ADO have an AutoIncrement property set to true? If so it should be false.

http://blogs.msdn.com/b/vsdata/archive/2009/09/14/refresh-the-primary-key-identity-column-during-insert-operation.aspx




回答3:


Have you verified the data is in the correct format? If I recall correctly Access will look like it worked with a text data type into a numeric field but won't work correctly.



来源:https://stackoverflow.com/questions/27492235/indexed-mysql-field-not-saving-value-when-creating-editing-record-through-ado

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!