線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:2372
推到 Plurk!
推到 Facebook!

ClientDataSet.RefreshRecord 造成 ApplyUpdate失敗

缺席
shininggod
一般會員


發表:16
回覆:20
積分:17
註冊:2009-05-13

發送簡訊給我
#1 引用回覆 回覆 發表時間:2011-05-03 15:42:14 IP:114.34.xxx.xxx 訂閱
錯誤訊息是"SQL Error Code :3988 不允許進行新交易,因為有其他執行緒正在工作階段中執行。"

ClientDataSet.Cancel;
ClientDataSet.RefreshRecord; //只是要修改前同期一次
ClientDataSet.Edit;
...
(改動資料)
...
ClientDataSet.Post;
ClientDataSet.ApplyUpdate(-1); //這裡炸

RefreshRecord 拿掉就沒問題, 換成 Refresh; 也沒問題, 在Delphi 2010也沒問題....
在Delphi XE (網路下載那個試用版) 就會出現上面的錯誤問題...

理論上是RefreshRecord重讀->寫了一次資料, 她以為有改過?
可是我是在那之後才Edit....Orz
TSQLquery裡面的key都有設好(要不2010就會炸)

最神奇的是我在ApplyUpdate之後也有呼叫RefreshRecord,可是(拿掉edit前的RefreshRecord)連續edit沒有問題Orz

另外測試

--前面啥都沒有, 所有ClientDataSet的event清空
ClientDataSet.Cancel; //沒有也一樣
ClientDataSet.RefreshRecord;
ClientDataSet.Delete;
ClientDataSet.ApplyUpdate(-1); //也是這裡炸

RefreshRecord是受到詛咒了嗎Orz?

因為新增的資料不能用 close -> open 刷新(where語法沒寫到)
更正前又想同步資料
refresh又是所有資料刷一次,沒必要...
cancer
高階會員


發表:58
回覆:319
積分:190
註冊:2004-07-31

發送簡訊給我
#2 引用回覆 回覆 發表時間:2011-06-15 20:02:40 IP:220.128.xxx.xxx 未訂閱
Hello, 我用 TAdoDataSet,Requery() 跟您的 RefreshRecord 作用差不多,有時候也會有問題,另外,ReQuery() 不會產生 AfterScroll,AfterScroll 事作的程式碼沒有執行到,所以,我後來都改用自定程序來做

procedure ReadData(KeyNo : string); // 全部透過此程序來讀取資料
begin
dsMain.Close;
dsDetail.Close;
if KeyNo = '' then // 轉入空白時讀取零筆
begin
dsMain.CommandText := 'select top 0 * from MainTable';
dsMain.CommandText := 'select top 0 * from DetailTable;
ellse begin // 否則讀取此編號的資料
dsMain.CommandText := Format(''select * From MainTable where KeyField = ''%s''', [KeyNo]);
dsDetail..CommandText := Format(''select * From DetailTable where KeyField = ''%s''', [KeyNo]);
end;
dsMain..Open;
dsDetail..Open;
end;

按新增按鈕
ReadData(''); // 讀取零筆以供新增
dsMain.Append;
dsDetail.Append;

按修改按鈕
ReadData(dsMain.FieldByName('KeyField'.AsString); // 重新讀取
if dsMain.RecordCount = 0 then // 上一次打開沒多久,其他人把它刪除掉了
ShowMessage('本單已刪除')
else begin
if dsMain.FieldByName('已審核').AsBoolean then // 上一次打開沒多久,其他人把它審核了
ShowMessage('本單已審核,不允許修改')
else begin
dsMain.Edit;
dsDetail.Edit;
DBEdit1.SetFocus;
end;
end;

按刪除按鈕
一樣要先重讀,再判斷筆數是否為零,再判斷是否已審核

重讀很重要,最好針對最前面的 DataSet 來下手,不要針對後方的 ClientDataSet。
您的 RefreshRecord 是 ClientDataSet 的 Refresh,看起來應該是前端 DataSet 的資料再填入 ClientDataSet,而不是前端 DataSet 再向資料庫再拿資料。
我沒有使用 DBExpress 這種單向 Cursor 的 DataSet,覺得這種單向 Cursor 不太好用,一直都使用 TAdoDataSet,LockType 設為 ltBatchOptimistic 就有 ClientDataSet 的效果。
編輯記錄
cancer 重新編輯於 2011-06-15 06:03:44, 註解 無‧
cancer 重新編輯於 2011-06-15 06:04:54, 註解 無‧
cancer 重新編輯於 2011-06-15 06:05:23, 註解 無‧
cancer 重新編輯於 2011-06-15 06:08:00, 註解 無‧
cancer 重新編輯於 2011-06-15 06:11:44, 註解 無‧
shininggod
一般會員


發表:16
回覆:20
積分:17
註冊:2009-05-13

發送簡訊給我
#3 引用回覆 回覆 發表時間:2011-06-16 11:47:04 IP:220.132.xxx.xxx 訂閱
我不敢用先讀的方式來判斷存在或是修改中 

如果程式中間當掉,變成要人工處理....Orz


我查不到clientdataset的文件, 只能推斷出2011 refresh(), refreshrecord有改

當初是為了少開一個連線,所以不用這種方式判斷,再修改前自己能同步的話就可以少開一個連線
M$ Sql超會卡彈, MARS 只能解決多筆資料讀取, 不能解決一筆修改 多筆讀取

反正現在看2011沒啥新東西,又換回2010了XD

系統時間:2017-10-24 17:34:58
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!