全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:1942
推到 Plurk!
推到 Facebook!

TADOTable連續寫入資料問題

答題得分者是:malanlk
kenbcb
中階會員


發表:171
回覆:129
積分:60
註冊:2003-07-15

發送簡訊給我
#1 引用回覆 回覆 發表時間:2005-09-07 10:27:49 IP:61.222.xxx.xxx 未訂閱
請問各位, 我用TADOTable元件,用Sleep(10) 的時間差,連續寫入一萬筆資料到MS SQL,但寫到一陣子時, 會出現 "資料儲存體中的資料列之關鍵值已被變更或刪除。現在已將區域資料列刪除。" 我是用 ADOTable1->Insert(); //....寫入值 ADOTable1->Post(); 望各位幫忙解決
kenbcb
中階會員


發表:171
回覆:129
積分:60
註冊:2003-07-15

發送簡訊給我
#2 引用回覆 回覆 發表時間:2005-09-09 15:54:01 IP:61.222.xxx.xxx 未訂閱
我查到的是連續寫入時, 會造成table lock住,,變得無法寫資料, 請問因如何解決呢?
malanlk
尊榮會員


發表:20
回覆:694
積分:577
註冊:2004-04-19

發送簡訊給我
#3 引用回覆 回覆 發表時間:2005-09-09 18:42:40 IP:203.69.xxx.xxx 未訂閱
把 LockType 改為 ltPessimistic 試試 或是 LockType 改為ltBatchOptimistic, 然後 每 1000 筆 補一個 ADOTable.UpdateBatch
kenbcb
中階會員


發表:171
回覆:129
積分:60
註冊:2003-07-15

發送簡訊給我
#4 引用回覆 回覆 發表時間:2005-09-11 09:25:25 IP:61.229.xxx.xxx 未訂閱
malanlk 你好, 我用Thread來負責寫table 並把 LockType 改為 ltPessimistic ,一樣會發生此問題; LockType 改為ltBatchOptimistic的話,因我用Thread好像不太適合也? 我是用clientsocket接收資料並將資料寫到buffer中, 用thread寫到db的.
malanlk
尊榮會員


發表:20
回覆:694
積分:577
註冊:2004-04-19

發送簡訊給我
#5 引用回覆 回覆 發表時間:2005-09-11 21:09:54 IP:61.219.xxx.xxx 未訂閱
請問你的 ADOConnection 也是放在 Thread 中嗎? 如果不是, 你有用 Synchronize 來做同步控制嗎?
kenbcb
中階會員


發表:171
回覆:129
積分:60
註冊:2003-07-15

發送簡訊給我
#6 引用回覆 回覆 發表時間:2005-09-12 09:07:43 IP:61.222.xxx.xxx 未訂閱
malanlk 你好, ADOConnection不是放在thread,而我也有用Synchronize,,只要連續寫多筆資料時,table就會發生沒法寫入,被lock住了
malanlk
尊榮會員


發表:20
回覆:694
積分:577
註冊:2004-04-19

發送簡訊給我
#7 引用回覆 回覆 發表時間:2005-09-12 09:32:50 IP:203.69.xxx.xxx 未訂閱
方便將程式(或部分程式) 貼上來 或 放到 會員求助區嗎?
kenbcb
中階會員


發表:171
回覆:129
積分:60
註冊:2003-07-15

發送簡訊給我
#8 引用回覆 回覆 發表時間:2005-09-12 11:30:47 IP:61.222.xxx.xxx 未訂閱
我的寫檔程式 note: 我要寫的data有可能會重覆; 但寫入時,發生錯誤訊息時,會由buffer中刪除.     
 
//---------------------------------------------------------------------------
void __fastcall DBThread::Execute()
{
  //---- Place thread code here ----
  while(!Terminated)
  {
    Synchronize(WriteDB);
    Sleep(10);
  }
}
//---------------------------------------------------------------------------
void __fastcall DBThread::WriteDB()
{
  if(!Form1->ADOConnection1->Connected) return;      if(Form1->GPSBuffer.size() > 0)
  {
    AnsiString DAY;
    int lonInt,latInt;
    float lonSouce,lonFloat,latSouce,latFloat;
    vector::iterator Ptr = Form1->GPSBuffer.begin();        try
    {
      DAY = AnsiString(Ptr->Timer,2) "/" 
            AnsiString(Ptr->Timer 2,2) "/" 
            AnsiString(Ptr->Timer 4,2) " " 
            AnsiString(Ptr->Timer 6,2) ":" 
            AnsiString(Ptr->Timer 8,2) ":" 
            AnsiString(Ptr->Timer 10,2);
      lonSouce = StrToFloatDef(AnsiString(Ptr->WGS_LON,sizeof(Ptr->WGS_LON)),0);
      lonInt = lonSouce/100;
      lonFloat = (lonSouce-lonInt*100)/60;
      latSouce = StrToFloatDef(AnsiString(Ptr->WGS_LAT,sizeof(Ptr->WGS_LAT)),0);
      latInt = latSouce/100;
      latFloat = (latSouce-latInt*100)/60;          Form1->ADOTableGPS->Insert();
      Form1->ADOTableGPS->FieldByName("Unit_id")->AsString = AnsiString(Ptr->ID,Max_GDTID_Len/2);
      Form1->ADOTableGPS->FieldByName("DateTime")->AsDateTime = StrToDateTime(DAY);
      Form1->ADOTableGPS->FieldByName("WGS_LON")->AsFloat = (float)lonInt lonFloat;
      Form1->ADOTableGPS->FieldByName("WGS_LAT")->AsFloat = (float)latInt latFloat;
      Form1->ADOTableGPS->FieldByName("Heading")->AsFloat = StrToFloatDef(AnsiString(Ptr->Heading,sizeof(Ptr->Heading)),0);
      Form1->ADOTableGPS->FieldByName("Speed")->AsFloat = StrToFloatDef(AnsiString(Ptr->Speed,sizeof(Ptr->Speed)),0)*1.853;
      Form1->ADOTableGPS->FieldByName("Sat")->AsInteger = (StrToIntDef(AnsiString(Ptr->Sat,sizeof(Ptr->Sat)),0) >= 9)?9:StrToIntDef(AnsiString(Ptr->Sat,sizeof(Ptr->Sat)),0);
      Form1->ADOTableGPS->FieldByName("IO1")->AsString = AnsiString(Ptr->IO1);
      Form1->ADOTableGPS->FieldByName("IO2")->AsString = AnsiString(Ptr->IO2);
      Form1->ADOTableGPS->FieldByName("IO3")->AsString = AnsiString(Ptr->IO3);
      Form1->ADOTableGPS->FieldByName("Data_type")->AsString = AnsiString(Ptr->Type);
      Form1->ADOTableGPS->Post();
    }
    catch(Exception &e)
    {
      AnsiString errMsg = AnsiString((char*)Ptr,sizeof(TGPSType));
      Form1->MsgWriteFile("Write DB Error.{" errMsg "}" e.Message);
    }
    Form1->GPSBuffer.erase(Ptr);
  }
}
//---------------------------------------------------------------------------
malanlk
尊榮會員


發表:20
回覆:694
積分:577
註冊:2004-04-19

發送簡訊給我
#9 引用回覆 回覆 發表時間:2005-09-12 12:49:00 IP:203.69.xxx.xxx 未訂閱
你確定 Insert ... Post 之間的 資料轉換都不會出問題嗎?    如果 資料轉換出問題 , Post 就會被跳過去, 也就是 ADOTableGPS 會維持 Insert 狀態, 造成 Lock ,所以你要在 except 中 檢查...    
    catch(Exception &e)
    {
      AnsiString errMsg = AnsiString((char*)Ptr,sizeof(TGPSType));
      Form1->MsgWriteFile("Write DB Error.{" errMsg "}" e.Message);
      if (ADOTableGPS->State==dsInsert) 
      {
        Form1->ADOTableGPS.Cancel();
      }
    }
kenbcb
中階會員


發表:171
回覆:129
積分:60
註冊:2003-07-15

發送簡訊給我
#10 引用回覆 回覆 發表時間:2005-09-12 15:06:41 IP:220.130.xxx.xxx 未訂閱
謝謝malanlk,,幫我解決此問題,, 請問我只有在thread 才有用到adotable 需要用Synchronize嗎? 感覺多筆資料時,會有畫面lay
malanlk
尊榮會員


發表:20
回覆:694
積分:577
註冊:2004-04-19

發送簡訊給我
#11 引用回覆 回覆 發表時間:2005-09-12 15:35:35 IP:203.69.xxx.xxx 未訂閱
如果畫面不想 delay 試試看在 WriteDB() 內加 Application->ProcessMessages();
系統時間:2024-11-23 10:08:50
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!