用DOA運行存儲過程(轉)

用DOA運行存儲過程(轉)

用Delphi開發C/S結構的Oracle數據庫軟件時,爲提高效率,通常將大批量的數據處理交給後臺存儲過程來完成。由於Delphi需通過BDE才能操作和處理各種數據庫文件,這樣不僅效率低,而且存在一定侷限性,所以考慮採用第三方工具DOA來提高交互效率,方便前後臺信息的傳遞。

DOA(即Direct Oracle Access的縮寫)是荷蘭Allround Automations公司開發的訪問Oracle的工具,運用DOA構件可以在Delphi或C++Builder開發環境下跳過BDE,而直接通過SQL Net訪問Oracle。初次接觸DOA,一些編程人員對怎樣運用DOA調用存儲過程感到困惑,筆者將結合電信綜合管理系統中數據加工審覈這一具體實例,詳細闡述其具體的方法和步驟。

實現方法
1.用TOraclePackage的CallProcedure/CallXXXFunction

用TOraclePackage的CallProcedure方法,我們就可簡單地調用Oracle存儲過程,該方法中參數以數組的形式傳遞。當TOraclePackage的ParameterMode屬性爲pmNamed時要按照名稱傳遞參數,每個參數前面必須有指定名稱的字符串,其格式爲:

CallProcedure(ProcedureName, [ParameterName1, Parameter1, ParameterName2, Parameter2…]);

當TOraclePackage的ParameterMode屬性爲pmPositional時,要按照位置傳遞參數:

CallProcedure(ProcedureName,[Parameter1, Parameter2,…]);

輸出參數通過傳遞parString、parInteger、parFloat、parDate或parBoolean常數來定義,輸出參數值在過程調用後用GetParameter方法獲得,格式爲:

PackageName.CallProcedure('ProcedureName',[parString]);
GetParameter(ParameterId);

如果沒有參數,則用parNone獲得:

PackageName.CallProcedure('ProcedureName', parNone);

與上面類似,我們用TOraclePackage的Call...Function 方法也可簡單地調用Oracle函數,只是根據返回值的不同,調用相應的方法CallBooleanFunction、CallDateFunction、CallFloatFunction、CallIntegerFunction或CallStringFunction。

2.用TOracleQuery或TOracleDataSet的Execute

用TOracleQuery或TOracleDataSet執行存儲過程的步驟爲:

(1)設置SQL屬性

將TOracleQuery或TOracleDataSet的SQL屬性設爲:

begin
ProcedureName (:Parameter1, : Parameter2, …);
end;

(2)定義參數

定義參數的方式有兩種,一是在對象查看器Properties選項卡的Variables屬性中,單擊省略號按鈕,打開變量屬性編輯器;二是用DeclareVariable方法。DOA支持PL/SQL 表,它可以作爲輸入/輸出參數傳遞給後臺存儲過程和函數,通過一次調用即可傳遞大量信息,使得在C/S結構中,網絡通信量顯著減少。在TOracleQuery 或TOracleDataSet中定義PL/SQL 表既可使用變量屬性編輯器(選中PL/SQL Table複選框,然後定義表的大小,如果是字符串型的,還需定義字符串大小),也可在運行時定義PL/SQL 表(先調用DeclareVariable方法定義變量,再調用DimPLSQLTable方法定義表大小)。

(3)參數賦值

給輸入參數賦值用SetVariable方法,給PL/SQL表賦值首先要創建數組變量,分別賦值數組的各元素,再通過該數組用SetVariable方法給PL/SQL表賦值。

ArrayName := VarArrayCreate([LowBounds, UpBounds], VarType);
Table[LowBounds] := value1;

Table[UpBounds] := valuen;
OracleQueryName.SetVariable(':TableName', ArrayName);

(4)執行存儲過程

調用Execute方法執行存儲過程,代碼如下:

OracleQueryName. Execute;

(5)獲得輸出參數

用GetVariable方法獲得輸出參數值, 輸入/輸出參數爲PL/SQL表時,返回的數組變量下限與輸入相同;輸出參數爲PL/SQL表時,返回的數組變量下限從零開始。

應用實例
以下是筆者運用上述第二種方法在電信綜合統計管理系統中調用加工審覈存儲過程的一段源代碼:

create or replace package pk_sh is
type t_object is table of varchar2(15) index by binary_integer;
type t_formula is table of number index by binary_integer;
procedure sp_audit(sh_time in varchar2,sh_dx in t_object,sh_gs in t_formula);
end pk_sh;

我們首先在服務器端創建包pk_sh,包中定義了兩種PL/SQL表,其中t_object存儲審覈對象,t_formula存儲審覈公式ID,存儲過程sp_audit根據傳遞的參數(時間、對象、公式)對後臺數據進行加工審覈。

客戶端用Delphi編寫,即通過DOA訪問sp_audit,具體源代碼如下:

Var
OracleSession1: TOracleSession;
OracleQuery1: TOracleQuery;
Begin
//連接數據庫
OracleSession1:= TOracleSession.Create(nil);
OracleSession1.LogonDatabase := 'chicago';
OracleSession1.LogonUsername := 'scott';
OracleSession1.LogonPassword := 'tiger';
OracleSession1.Connected:= True;
OracleQuery := TOracleQuery.Create(nil);
OracleQuery1.Session := OracleSession1;
//創建數組並賦值
sh_dx:=VarArrayCreate([0, LV_object.Items.Count -1], varVariant);
for i:=0 to LV_object.Items.Count -1 do
begin
sh_dx[i] :=LV_object.Items[i].caption;
end;
sh_gs:=VarArrayCreate([0, LV_formula.Items.Count -1], varVariant);
for i:=0 to LV_formula.Items.Count -1 do
begin
sh_gs[i] :=strtoint(LV_formula.Items[i].caption);
end;
sql_str :='pk_sh.sp_audit(:sh_time,:sh_dx,:sh_gs);';
with OracleQuery1 do
begin
//設置SQL屬性
Clear;
SQL.Add('begin');
SQL.Add(' ' + sql_str );
SQL.Add('end;');
//定義參數
DeleteVariables;
DeclareVariable('sh_time', otString);
DeclareVariable('sh_dx', otString);
DeclareVariable('sh_gs', otInteger);
DimPLSQLTable('sh_dx', 2000, 15);
DimPLSQLTable('sh_gs', 500, 0);
//參數賦值
SetVariable(': sh_time ', sh_time);
SetVariable(':sh_dx', sh_dx);
SetVariable(':sh_gs', sh_gs);
//執行存儲過程
Execute;
Free;
end;
OracleSession1.Connected:= False;
OracleSession1.Free;
End;

以上源代碼採用Delphi 5、Oracle 8開發,在Windows 98/Windows2000系統平臺下調試通過。

通過以上分析可知,利用BDE訪問Oracle,由於它不支持PL/SQL表,參數只能分行傳遞,需反覆多次調用存儲過程,而用DOA 則使問題圓滿解決。此外,將TOracleQuery的Threaded屬性設置爲True,就可簡單地編寫多線程應用程序,而將Debug屬性設置爲True,可在運行時顯示SQL語句和變量值,以方便調試。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章