----在實際的mis系統中,遠端資料庫訪問大多通過modem連線,出於通訊費用及速度方面的考慮,往往採用先將資料儲存在本地,然後集中傳送到遠端的辦法。遠端資料傳送可以有多種方案,最常見的是先將要傳送的資料打包成檔案,在利用檔案傳輸形式傳送到目的地,在目的地對資料恢復後新增到本地資料庫中。這種方法普遍地應用於**交易系統,其優點是速度快,並且可事先對資料壓縮,更大限度地節約傳送時間及費用。但這種方案也有其不足之處:由於利用檔案傳輸機制,無法利用資料庫本身的特性如完整性約束、資料一致性、回滾機制等,因此在比較複雜的資料庫系統中較少採用。另一種方法是直接將兩端處理成"客戶/伺服器"模式,將資料傳送看成是向server提交資料。由於這種方案充分利用了資料庫伺服器的特性,並且實際操作基本與區域網方式一致,因此本文將詳細介紹這種方案。另外本文的部分內容是基於delphi/cbuilder的。
----由於傳輸速度的原因,當傳送大量資料時絕對不贊成逐條記錄地向伺服器提交資料,而應批量地向server提交,delphi/cbuilder中提供了乙個tbatchmove控制項專門用於批量傳送資料,利用它可極大減少網路負擔,提高傳送速度。遺憾的是,tbatchmove控制項只提供了簡單的錯誤控制功能,沒有提供顯示傳送進度、使用者終止傳送等重要功能。然而tbatchmove所依賴的bde卻提供了一種"**機制"可以完成上述兩個功能。所謂"**"過程是這樣的:當bde執行某種操作時,比如從一張表向另一張表拷貝大量資料的過程中,每過一段時間(如需要顯示拷貝進度時),bde會呼叫一段你自己寫的函式(**函式),以幫助你更完全地控制程式。這種做法有點想dlphi中的event(事件)及事件處理函式--某個具體的操作動作會讓vcl觸發某個事件,從而呼叫一段你寫好的事件處理函式,不同的事件會觸發不同的處理函式。
----為了讓bde能正確地與你的函式協同工作,你必須事先"註冊"你的函式,讓bde知道某個事件發生時應呼叫(**)你的某段**。bde提供了乙個dbiregistercallback註冊函式,不幸的是,bde的聯機幫助中的說明不能適合於delphi/cbuilder,按照該說明編寫的程式根本不能通過編譯!筆者通過實踐找到了正確使用bde**函式的方法,下面將詳細介紹該機制的使用。bde**機制包含以下幾個步驟:
----1)按bde的預定格式編寫你的**函式
----2)呼叫dbiregistercallback函式註冊你的**函式,這樣當你執行相關資料庫操作時就自然地觸發你的**函式。
----3)執行相關資料庫操作,比如batchmove1->exectue();
----4)登出該**函式
----其中最關鍵的是正確註冊你的**函式,因此先介紹第二步。(註冊與登出都呼叫同一函式,只是最後乙個引數略有不同)
----首先你應知道在哪類"事件"發生時呼叫你的**函式,其次你應明白與該事件相關的引數及資料結構--這一切都發生在呼叫dbiregistercallback函式註冊時,所以下面先介紹dbiregistercallback的正確用法及說明:
----在原bde幫助中該函式的原形(c)是這樣的
dbiresult dbifn dbiregistercallback (hcursor, ecbtype, iclientdata, icbbuflen, pcbbuf, pfcb);
----要使用該函式必須include標頭檔案,問題是delphi/cbuilder中根本沒有提供該檔案,取而代之的是"bde.hpp",但是在包含進該檔案後程式仍然不能編譯通過,因為該檔案中沒有dbifn等的說明。乙個簡單的方法是在**中去掉dbifn。函式中各引數解釋如下:hcursor是乙個bde中物件的控制代碼,如果這個引數為null,則表示註冊的**函式適合於所有bde任務;第二個引數ecbtype是指**函式的觸發條件的類別,有很多種型別可以選擇,其中cbgenprogress表示當需要顯示乙個長操作的進度時觸發這個**函式;第三個引數iclientdata是傳遞給**函式的某個資料結構的指標,在我們的例子中為null;第四個引數icbbuflen是指**buffer的大小,該大小隨第二個引數的不同而不同,比如sizeof(cbprogressdesc);第五個引數pcbbuf是**buffer的指標,該指標型別隨第二個引數變化,比如cbgenprogress的資料結構是cbprogressdesc;最後乙個引數是**函式的位址指標,當該引數為null時表示登出該型別的**函式。關於**函式將在稍後詳細介紹。下面是註冊首席執行官操作時顯示進度的**函式的格式:
int rst= dbiregistercallback (null,
//適合於任何程序
cbgenprogress, //**型別:顯示長操作的進度
null, //沒有資料
sizeof(cbprogressdesc), //資料結構的大小
&acbbuf, //資料的記憶體位址
apicallbackfun //**函式的位址
); ----接下來就應該完成第一步:編寫**函式
----在c中,**函式應如下宣告:
cbrtype__stdcallapicallbackfun(
cbtyp eecbtype,//**型別
int iclientdata,//**資料(指標)
void *pcbinfo//**資料結構指標
) ----第乙個引數是**型別;第二個引數是**資料,其解釋同dbiregistercallback的第三個引數;第三個是**資料的指標,該資料的結構隨**型別的不同而不同。比如進度指示cbgenprogress的資料結構是cbprogressdesc,其定義如下:
struct cbprogressdesc ;
----該結構的兩個域同時只有乙個起作用,第乙個表示操作的進度百分比,當其為-1時表示第二個域起作用。第二個域用字串表示進度資訊,其格式為<:>,比如:recordscopied:125
----本文主要在**函式中完成兩個工作:
----1)顯示資料拷貝(batchmove)進度
----2)提供讓使用者終止長時間拷貝的機制
----顯示拷貝進度的**如下:
cbrtype __stdcall apicallbackfun(
cbtype ecbtype, // callback type
int iclientdata, // client callback data
void * pcbinfo // call back info/client)
else
return cbrcontinue;
//必須返回cbrcontinue以便讓batchmove繼續
//若返回cbrabort則終止拷貝
} ----一切完成以後,每當呼叫長時間bde操作(比如batchmove1->exectue())時都會觸發該**函式,注意在不需要時應"登出"這個**函式。
----如果批量傳送資料時間很長,則必須為使用者提供終止該操作的機會,前面提到,若**函式返回cbrabort,則batchmove過程立即終止。可以在form上加上乙個"停止"按鈕和乙個全域性布林變數iscontinue,當開始拷貝時設該變數為true,當按鈕按下後,設該變數為false,每次呼叫**函式時檢查iscontinue的值,若為true則**函式返回cbrcontinue讓拷貝繼續,否則返回cbrabort終止拷貝。但是問題在於一旦拷貝過程開始,該程序內所有訊息將被阻塞,應用程式在拷貝結束之前沒有機會響應鍵盤、滑鼠等一切訊息,連螢幕重新整理都不能完成,因此必須找到一種避免訊息阻塞的方法。
----大家知道,windows是靠事件(訊息)驅動的,在win32系統中有兩種訊息佇列:系統佇列和應用程式佇列,當乙個程式進行乙個長時間操作時,系統分配給該程式的時間片將完全用於處理該操作,換句話說,應用程式沒有從它的應用程式佇列中取出訊息並處理的機會,這樣該程式將停止一切對外部事件的響應直到該操作完成為止。具體到本文中就是程式必須等到batchmove1->execute()執行完畢後才能響應使用者操作,因此使用者將完全沒有機會終止拷貝過程。
----解決的辦法是:在**函式中取出訊息佇列中的訊息,並後台處理它們,這樣使用者將有機會按下終止按鈕。實現的**很簡單,在**函式中最後加入以下**即可
cbrtype __stdcall apicallbackfun(…)
if (iscontinue)
return cbrcontinue;
else
return cbrabort;
} ----以上的**雖然都用cbuilder編寫,但是其原理同樣適用於delphi
遠端資料傳輸方法 putty pscp
遠端資料傳輸的方法很多,以前曾經用過ssh協議實現本地windows與遠端linux的通訊,這裡介紹一下乙個較常用的遠端傳輸工具putty的使用。首先然後配置環境變數 在系統變數的path中新增putty的安裝路徑,預設的是 c program files putty 單純使用putty並不需要配置...
關於遠端主機的資料傳輸
場景附註參考 經常需要向遠端主機傳檔案,實際情況中要考慮到多種場景。這種方式特別適合大檔案傳輸,比如達到gb級別時,可以考慮使用ftp及sftp。待補充更多資料。在securecrt中,可以使用rz命令上傳檔案,不過通常只能上傳幾十mb的檔案。有時新增引數 be,可以傳輸上百mb的檔案。至於更大的檔...
資料傳輸 入門資料傳輸服務,建立你的資料遷移任務
資料傳輸服務dts data transmission service 提供的資料遷移功能簡單易用,您只需在控制台上進行簡單操作,即可完成整個遷移任務的配置。注意事項本文僅簡單介紹資料遷移任務的通用配置流程,不同的資料來源在配置遷移任務時略有不同。關於各類資料來源的詳細配置案例請參見dts資料遷移方...