Delphi分布式系统(MIDAS)中动态调用存储过程 From: www.ccw.com.cn

一、前言

    现在,多层应用程序已经和其他计算机技术一样越来越多地被谈论。多层应用程序和传统的客户/服务器应用程序相比,前者有更多的优点。而B o r l a n d的Multitier Distr ibuted Application Services Suite(MIDAS)可以更加快速的建立多层应用程序。

    MIADS中通过服务端DataSetProvider组件和客户端ClientDataSet组件对数据集的操作进行良好的封装,但到对存储过程的调用却有些不足之处---对于存储过程没有result返回的不能进行客户端调用/有result的客户端不能取到result的返回值。所以本文讲述一种在MIDAS中动态调用存储过程的技巧。

二、原理说明

1. 在客户端添加SocketConnection(或DCOMConnection)和ClientDataSet并进行相应关联设定。

2. 添加ADOStoredProc组件,对ADOStoredProc的ProcedureName和Parameters进行常规设定。

3. 通过MidasAdoProc过程(自行编写)把ADOStoredProc组件的信息转换为Variant数组,再用ClientDataSet的DataRequest方法把Variant数组上传。

4. 触发服务器DataSetProvider的OnDataRequest事件,在OnDataRequest对上传的Variant数组进行解析,用相应的信息更新服务器的ADOStoredProc组件。

5. 执行服务器的ADOStoredProc组件,转换服务器的ADOStoredProc组件的执行结果为Variant数组,将Variant数组回传客户端。

6. 客户端对用回传的Variant数组更新客户端的ADOStoredProc

7. 对本地ADOStoredProc进行执行后的常规操作

三、使用例程

3.1 例程环境

服务器端安装了ORACEL 9I数据库或ORACEL 9客户端数据库,数据库情况如下:

实例名my9i,用户will,用户密码will,在will用户下建立存存储过程TESTDELPH,脚本如下

CREATE OR REPLACE PROCEDURE TESTDELPHI (ins varchar,

outs out varchar) is

begin

outs:='my info ' || ins || 'ok';

return ;

end testdelphi;

编程工具DELPHI5(DELPHI6/7方法相同不过就是组件位置有些变化)

服务器主机ip:192.168.0.118,主机名will

3.2 公共函数midas_tools.pas

unit midas_tools;

interface

uses

DBClient,ADODB;

//Parameters转换为Variant数组

function ParametersToVariant(par:TParameters;ProcedureName:Variant): OleVariant;

//Variant数组转换到Parameters

function VariantToParameters(input:Variant;par:TParameters):Variant;

//MIDAS调用PROC的通用程序

procedure MidasAdoProc(MyProc:TADOStoredProc;MyClientDataSet:TClientDataSet);

implementation

//Parameters转换为Variant数组

function ParametersToVariant(par:TParameters;ProcedureName:Variant): OleVariant;

var

tmpv:Variant;

n,i:integer;

begin

tmpv:=VarArrayCreate([0,par.Count*5+1],VarVariant);

tmpv[0]:=ProcedureName;

tmpv[par.Count*5+1]:='this is fro Midas';

n:=0;

i:=0;

while par.Count>i do begin

tmpv[n+1]:=par.Items[i].Name;

tmpv[n+2]:=par.Items[i].DataType;

tmpv[n+3]:=par.Items[i].Direction;

tmpv[n+4]:=par.Items[i].Size;

tmpv[n+5]:=par.Items[i].Value;

i:=i+1;

n:=n+5;

end;

result:=tmpv;

end;

////Variant数组转换到Parameters

function VariantToParameters(input:Variant;par:TParameters):Variant;

var

n,i:integer;

begin

n:=0;

i:=0;

while VarArrayHighBound(input,1)>(n+5)do begin

par.CreateParameter(input[n+1],input[n+2],input[n+3],input[n+4],input[n+5]);

n:=n+5;

end;

result:=true;

end;

//MIDAS调用PROC的通用程序

procedure MidasAdoProc(MyProc:TADOStoredProc;MyClientDataSet:TClientDataSet);

var

ins,outs:Variant;

begin

ins:=ParametersToVariant(MyProc.Parameters,MyProc.ProcedureName);

outs:=MyClientDataSet.DataRequest(ins);

MyProc.ProcedureName:=outs[0];

MyProc.Parameters.Clear;

VariantToParameters(outs,MyProc.Parameters);

end;

end.

3.3 编写MIDAS服务端程序

3.3.1 建立应用程序:

点击File|New菜单下的New Application或New Items中的Application,如图3-1如示

图3-1

3.3.2 建立远程数据模块:

点击File|New….菜单New Items中的multitier页中Remote Data Module的,如图3-2如示

图3-2

出现图3-3,在CoClass Name内添入MidasAdoProc,Threading Model中选取Free(使用ADO对象用Free要好一些),点击OK

图3-3

3.3.3 添加数据集组件:

ADOStoredProc1(ADO页面中)和DataSetProvider1(Midas页面中),如图3-4所示

图3-4

设定ADOStoredProc1的ConnectionString属性为‘Provider=MSDAORA.1;Password=will;User ID=will;Data Source=my9i;Persist Security Info=True’,字苻串可以通过building产生。

3.3.4 存储文件:

窗体单元(Unit1.pas)存储为mainf.pas,服务器单元(Unit2.pas)存储为server.pas,项目文件为MIDASPROC_S.dpr,在server.pas文件中通过uses unit选择mainf;以使在server.pas中对主窗体进行调用。

3.3.5 添加服务器通用处理代码

通过View|Project Manager对Server.pas添加使用midas_tools

图 3-5

以下为具体代码(其中粗体部分为手工添加,斜体为向导自行添加,也是说自定义的函数放在了{$R *.DFM}下面):

implementation

uses mainf,midas_tools;

{$R *.DFM}

3.3.6 在DataSetProvider1组件的事件OnDataRequest(图3-6)中添加处理代码

图3-6

代码如下(其中粗体部分为手式添加,斜体为向导自行添加):

function TMidasAdoProc.DataSetProvider1DataRequest(Sender: TObject;

Input: OleVariant): OleVariant;

begin

if VarIsArray(input) then

begin

if input[VarArrayHighBound(input,1)]='this is fro Midas' then

begin //调存储过程

Form1.Caption:='proc='+input[0];

self.ADOStoredProc1.ProcedureName:=input[0];

self.ADOStoredProc1.Parameters.Clear;

VariantToParameters(input,self.ADOStoredProc1.Parameters);

self.ADOStoredProc1.ExecProc; result:=ParametersToVariant(self.ADOStoredProc1.Parameters,self.ADOStoredProc1.ProcedureName);

end else

Form1.Caption:='来源信息非存储过程信息不明';

end else

Form1.Caption:='来源信息不明';

end;

3.3.7 服务端程序设定

服务端程序编译并执行一次,完成注册功能,并执行"C:\Program Files\Borland\Delphi5\Bin\scktsrvr.exe”,启动socke服务.

3.4 编写MIDAS客户端程序

3.4.1 建立应用程序:点击File|New菜单下的New Application或New Items中的Application,如图3-1如示

3.4.2 建立相关组件:

建立四个组件,分别为ADOStoredProc1、SocketConnection1、ClientDataSet1、 Button1、 Edit1如图3-7所示

图3-7

设定SocketConnection1的host为服务器主机名,本例为will或者address为主机IP,

ServerName为MIDASPROC_S.MidasAdoProc。

设定ClientDataSet1.RemoteServer为SocketConnection1

ClientDataSet1.ProviderName为DataSetProvider1

3.4.3 添加相关通用代码

在Unit1.pas,申明使有midas_tools:

implementation

{$R *.DFM}

uses

midas_tools;

3.4.4 添加处理代码

双击Button1 (其中粗体部分为手工添加,斜体为向导自行添加)

procedure TForm1.Button1Click(Sender: TObject);

begin

if self.SocketConnection1.Connected=false then self.SocketConnection1.Open;

self.ADOStoredProc1.Parameters.Clear;

self.ADOStoredProc1.ProcedureName:='TESTDELPHI'; //动态调用在本处改存储过程名

self.ADOStoredProc1.Parameters.CreateParameter('INS',ftString,pdInput,2000, self.Edit1.Text);

self.ADOStoredProc1.Parameters.CreateParameter('OUTS',ftString,pdOutput,2000,'NUll');

//原来的self.ADOStoredProc1.ExecProc; 改为下面的

MidasAdoProc(self.ADOStoredProc1,self.ClientDataSet1);

ShowMessage('存储过程返回'+self.ADOStoredProc1.Parameters.ParamValues['OUTS']);

end;

3.5 执行

运行客户端程序

在客户端输入”这是测试”

单击”Button1”后返回

服务端显示的信息

3.6 小结

在实际的应用中通过动态修改ADOStoredProc1.ProcedureName和self.ADOStoredProc1.Parameters后执行

MidasAdoProc(self.ADOStoredProc1,self.ClientDataSet1);

就可以达到动态调用存储过程的目的。

程序已经在delphi5/6/7和ORACEL9I和Ms sql2000环境完全测试通过。

注:在sql2000中存储过程中常用return xx的形式进行返回值,在ADOPROC的Parameters中用,CreateParameter('@RETURN_VALUE’, ftInteger, pdReturnValue,0,NUll);设定为第一个参数,才能正常使用。

posted on 2005-02-23 11:06  Eagletian  阅读(2383)  评论(1编辑  收藏  举报

导航