uniDAC用法總結

hrdzkj發表於2013-06-07

http://blog.sina.com.cn/s/blog_44fa172f0101dntl.html

常言道,細微之處見體貼。UniDAC有一些過人的方法或屬性。
比如,重新整理單條記錄(RefreshRecord)、多表更新的屬性(UpdatingTable)、巨集替換引數(Macros)、
整合刪除/新增/修改/重新整理/鎖定SQL語句、FetchRows,更讓人稱道的是引入了UpdateSQL元件。

TUniTable、TUniQuery和TUniStoredProc是用來檢索和編輯資料的UniDAC控制元件.

***************************TUniQuery******************************************************

UniDirectional屬性

ADO沒有單向資料集特性,所有的資料下載到本地,不停的開闢記憶體或釋放大記憶體,對三層的記憶體是一個極大考驗。TUniQuery有一個 UniDirectional屬性,支援單向速度,這點和DBX的想法不謀而合。況且,單向資料集特性速度非常快,在三層中,配合 TDataSetProvider,中介軟體將其Data包傳送到客戶端,速度無可比擬。ADO也有流或XML格式包,但無論是XML或流格式,資料包遠比 CDS的包大幾倍。CDS封包技術很好!


FetchRows可以設定一次獲取記錄的行數

uniquery 和 unitable 的 SpecificOptions 屬性,需要設定 FetchAll=False才能使 FetchRows 的設定生效,而預設情況下, oracle 是設定Oracle.FetchAll=False;
而對去 sql server 和 mysql 等,卻是設定的 XXX.FetchAll=True 
UniQuery.SpecificOptions.Values['FetchAll'] := BoolToStr(cbFetchAll.Checked, True);

UniDirectional屬性

ADO沒有單向資料集特性,所有的資料下載到本地,不停的開闢記憶體或釋放大記憶體,對三層的記憶體是一個極大考驗。TUniQuery有一個 UniDirectional屬性,支援單向速度,這點和DBX的想法不謀而合。況且,單向資料集特性速度非常快,在三層中,配合 TDataSetProvider,中介軟體將其Data包傳送到客戶端,速度無可比擬。ADO也有流或XML格式包,但無論是XML或流格式,資料包遠比 CDS的包大幾倍。CDS封包技術很好!

UniDAC的單條記錄重新整理
1、設定 SQLRefresh.TEXT的重新整理SQL,一般要具體到單條記錄。比如:SQLRefresh.Text:='SELECT * FROM TName WHERE ID = :ID'(其中ID是表TName的主鍵,以確保返回只有一條記錄)
2、設定 TRefreshOptions為 [roAfterInsert,roAfterUpdate],即為新增後重新整理,修改後重新整理。
3、呼叫 UniQuery1.RefreshRecord
如果不做以上設定,僅執行UniQuery1.RefreshRecord 是一點反映也沒有的

UpdatingTable
屬性 UpdatingTable 服務顯示錶將被更新(如果在查詢中有許多表)。如果它的值為空,正在使用的表就會顯示SQL操作的結果。為了更好地對查詢結果進行操作,建議應總是設定屬性UpdatingTable

cachedupdates快取更新
UniQuery預設狀態為行提交,使用前根據需要設定readonly或cachedupdates屬性

Filter過濾
UniQuery.Filter預設大小寫區分,請注意設定FilterOptions屬性([foCaseInsensitive]),TVirtualtable也存在相同情況

在UniQuery的SQL定義引數
我們經常會在UniQuery的SQL定義一些引數,在傳參時,需要特別注意,例如:
QExec.Close;
QExec.SQL.Text:= ‘select * from YHB where sYHBH=_YHBH’;
在傳參時有兩種寫法
1)最穩妥的寫法
QExec. ParamByName(‘P_YHBH’).DataType:= ftString;
QExec. ParamByName(‘P_YHBH’).ParamType:= ptInPut;
QExec. ParamByName(‘P_YHBH’).AsString:= ‘張三’;(此處可將AsString換成Value)
2)下面這個寫法我做了簡單測試,也是可以的,但對複雜的SQL傳參是否正確,未知
QExec. ParamByName(‘P_YHBH’).AsString:= ‘張三’;(在不對引數的資料型別和傳入傳出型別進行指定的情況下,絕對不能使用Value)

UniQuery.SetReadOnly屬性
1) 我們經常會用到多表關聯,且需要在前臺修改資料。舉個例子:a表和b表,在前臺兩個表欄位都需要修改,則需要將SetReadOnly設定成false
2)特別注意:若將一個UniQuery.SetReadOnly設定成true,而這個表有一個自增長ID,那麼你在提交資料時會出錯,跟蹤SQL會發現,ID被前臺前行傳了一個null值

UniQuery. RefreshRecord

可以重新整理當前選擇的資料

資料提交

資料提交的順序,一定要注意:

   with MyQuery do
   begin
      Session.StartTransaction;
      try
         ... {Modify data}
         ApplyUpdates; {try to write the updates to the database}
         Session.Commit; {on success, commit the changes}
      except
         RestoreUpdates; {restore update result for applied records}
         Session.Rollback; {on failure, undo the changes}
         raise; {raise the exception to prevent a call to CommitUpdates!}
      end;
      CommitUpdates; {on success, clear the cache}
end;
對於單資料集的提交:
MyQuery. ApplyUpdates;
MyQuery. CommitUpdates;

Unidac:解決“trying to modify read-only Field”問題!
後臺使用SQL語句中,經常會關聯自定義函式或檢視,而CDS(TClientDataSet)對欄位校驗比較嚴格,涉及到的自定義函式或檢視輸出的欄位,都會強制改為ReadOnly為True屬性。
當後臺使用UniDAC+CDS,關聯檢視或自定義函式,為了資料一致性,有可能需要在前臺介面上修改CDS相關的自定義函式輸出的欄位,即便是將該欄位設定為 readonly為false,

或將其欄位的 FieldDefs屬性的attributes的faReadOnly去掉,系統也會丟擲一個異常:trying to modify read-only Field。
解決問題很簡單,將TUniQuery.Options.SetFieldsReadOnly為false即可。
查一下TUniQuery.Options.SetFieldsReadOnly的幫助,這樣寫道:
If True, dataset sets the ReadOnly property to True for all fields that do not belong to UpdatingTable or can not be updated. Set this option for datasets
that use automatic generation of the update SQL statements only.

Macros屬性

要注意:如果要替換的值是一個字串,那麼記得在字串兩邊加''號,因為Macro只是一個簡單的替換功能,他不會去判斷條件的型別。

其他

UniQuery預設情況下,有些varchar型別的欄位有自動加了一個空格,請注意設定Options.TrimVarChar=true
UniQuery在進行Insert時,若欄位不能為null且前臺操作未填寫時,可能會報錯,請設定RequiredFields=true
UniQuery在修改資料集時,預設的方式是按關鍵字生成SQL語句進行資料提交。還有另外兩種方式:一是設定updateSQL,一是設定KeyFields(具體請sql跟蹤檢視)
UniQuery的資料排序屬性是IndexFieldNames

********************儲存過程*************************************************************************

TUniConnection, TUniSQL, TUniQuery, TUniStoredProc均可以執行儲存過程。

TUniConnection:

是一種最簡單的執行儲存過程的控制元件,但他有很多限制。TUniConnection不能具有SQL、儲存過程名和引數,不支援輸出引數也不支援儲存執行的預準備。當然,如果只是執行一個既沒有返回也沒有輸出引數設定,那TUniConnection是一個不錯的選擇。

TUniSQL:TUniSQL是一個被分離出的小控制元件,執行SQL語句但不返回結果集。它沒有資料儲存,但要消耗一些記憶體,但比TUniQuery和TUniStoredProc的執行速度快。

UniSQL.SQL.Text :=str
 UniSQL.Execute;
 s := 'Rows affected: ' + IntToStr(UniSQL.RowsAffected);


TUniQuery:TUniQuery除具有TUniSQL的執行功能外,還能返回結果集。

TUniStoredProc:TUniStoredProc是專門用來執行儲存過程的一個控制元件,可以返回結果集、輸出引數、執行準備以及通過CreateProcCall方法初始化等。

1、 引數型別

UniDAC支援四種引數型別:input, output, input/output, result

***********************************************TUniConnection************************************************************

事務

TUniConnection通過StartTransaction, Commit, Rollback等方法來控制本地事務,判斷一個事務是否開啟用InTransaction。

1TUniConnection

建立和控制元件資料連線的控制元件,能訪問的資料庫包括:Oracle, SQL Server, MySQL, InterBase, Firebird, 和PostgreSQL.

雖然UniDAC對不同的資料庫提供了統一的訪問介面,但是對個別資料庫還是要進行一些特殊的設定,這些設定是一個字串列表,你可以按以下程式碼進行設定:

UniConnection.SpecificOptions.Values['CharLength'] := '1';

1、 Oracle