用ADO更新MYSQL報“無法為更新定位行。一些值可能已在最後一次讀取後已更改”問題的解決,adomysql

來源:互聯網
上載者:User

用ADO更新MYSQL報“無法為更新定位行。一些值可能已在最後一次讀取後已更改”問題的解決,adomysql

今天在DELPHI中用ADO通過ODBC連MYSQL更新資料時遇到這個奇怪的錯誤:無法為更新定位行。一些值可能已在最後一次讀取後已更改。


百思不得其解,於是上網查。有的說是因為沒主鍵,但我這個表是有的;有的說是有預設值,我檢查了一下,所有欄位都是沒預設值的;有的說是先INSERT再EDIT導致的,我這就是純EDIT、POST,沒有INSERT,所以也不存在。

又找了半天,終於找到類似情況,有人說如果EDIT修改的資料與原有資料一樣,那POST時就會報這個錯誤。我檢查了一下,還真是,我EDIT其實給欄位賦的值是跟修改前一樣的,如果稍加改動,欄位值有不一樣,就能正常POST提交了。解決辦法只能是給欄位賦值前判斷一下值是否相同,真夠BT的。

問題到此算是解決了,但為啥會這樣呢?通過開啟ODBC追蹤記錄檔進行分析,我們大概能猜到了原因。下面這段是給所有欄位賦相同值的SQL追蹤記錄檔:

BEXE            13f4-1118EXIT  SQLExecDirectW  with return code 0 (SQL_SUCCESS)
HSTMT               0x0362C568
WCHAR *             0x0B774FC8 [      -3] "UPDATE `test`.`table1` SET `table1ID`=?,`CONTID`=?,`NAME`=?,...`BKWFID`=? WHERE `table1ID`=? AND `CONTID`=? AND ... AND `BKWFID`=?\ 0"
SDWORD                    -3

BEXE            13f4-1118 EXIT  SQLRowCount  with return code 0 (SQL_SUCCESS)
HSTMT               0x0362C568
SQLLEN *            0x0018E804 (0)
注意這時SQLRowCount返回結果是0,意思是更新了0行。

下面這個則是賦值有變化的SQL追蹤記錄檔:
BEXE            13f4-1118 EXIT  SQLExecDirectW  with return code 0 (SQL_SUCCESS)
HSTMT               0x0362C568
WCHAR *             0x0B76FEC8 [      -3] "UPDATE `test`.`table1` SET `table1ID`=?,`CONTID`=?,`NAME`=?,...`BKWFID`=? WHERE `table1ID`=? AND `CONTID`=? AND ... AND `BKWFID`=?\ 0"
SDWORD                    -3

BEXE            13f4-1118 EXIT  SQLRowCount  with return code 0 (SQL_SUCCESS)
HSTMT               0x0362C568
SQLLEN *            0x0018E804 (1)

這時SQLRowCount返回結果是1,意思是更新了1行。

兩個SQL一模一樣,區別只在於前一個SQL執行後記錄內容沒有變化,而後一個是有變化!然後對於沒變化的情況MYSQL就告訴你,你沒有UPDATE任何記錄,其實你是UPDATE了一條記錄,只是UPDATE前後結果一樣,跟沒有UPDATE的效果相同,於是MYSQL返回了0,於是ADO認為沒UPDATE到資料,於是認為是別人把資料修改掉了,於是就報“無法為更新定位行”的錯誤了。

補充:

後來接著研究,為了驗證這個問題,直接用SQL命令更新一條NAME='公告'的記錄:

mysql> update table1 set name='公告' where table1id=1;
Query OK, 0 rows affected
Rows matched: 1  Changed: 0  Warnings: 0

mysql> update table1 set name='公告1' where table1id=1;
Query OK, 1 row affected
Rows matched: 1  Changed: 1  Warnings: 0

mysql>

顯然是因為相同值時返回的0 rows affected導致了問題。

然後再上網搜尋時,發現MYSQL官方有這個問題的說明,只需要修改MYSQL的ODBC串連配置即可解決:

http://dev.mysql.com/doc/connector-odbc/en/connector-odbc-errors.html

Write Conflicts or Row Location Errors

How do I handle Write Conflicts or Row Location errors?

If you see the following errors, select the Return Matching Rows option in the DSN configuration dialog, or specifyOPTION=2, as the connection parameter:

Write Conflict. Another user has changed your data.Row cannot be located for updating. Some values may have been changedsince it was last read.

於是照著修改了一下ODBC的串連配置:

改完後,重啟應用程式,果然一切正常了。


DELPHI中出現了不可以為更新定位行,一些值可可以已在最後一次讀取後已更改"S的警告

在修改之前先重新整理一下資料!
 
VB:不可以為更新定位行, 一些值可可以已在最後一次讀取後以更改

這是因為資料庫以獨佔方式開啟了
 

相關文章

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.