首页 | 社区 | 博客 | 招聘 | 文章 | 新闻 | 下载 | 读书 | 代码
亲,您未登录哦! 登录 | 注册

Delphi开发用DOA运行存储过程

打印文章

分享到:
陶占红

  用Delphi开发C/S结构的Oracle数据库软件时,为提高效率,通常将大批量的数据处理交给后台存储过程来完成。由于Delphi需通过BDE才能操作和处理各种数据库文件,这样不仅效率低,而且存在一定局限性,所以考虑采用第三方工具DOA来提高交互效率,方便前后台信息的传递。

  DOA(即Direct Oracle Access的缩写)是荷兰Allround Automations公司开发的访问O
racle的工具,运用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语句和变量值,以方便调试。

本栏文章均来自于互联网,版权归原作者和各发布网站所有,本站收集这些文章仅供学习参考之用。任何人都不能将这些文章用于商业或者其他目的。( Pfan.cn )

编程爱好者论坛

本栏最新文章