惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Google DeepMind News
Google DeepMind News
N
Netflix TechBlog - Medium
The Register - Security
The Register - Security
C
Cybersecurity and Infrastructure Security Agency CISA
H
Hackread – Cybersecurity News, Data Breaches, AI and More
The Hacker News
The Hacker News
P
Proofpoint News Feed
Project Zero
Project Zero
The GitHub Blog
The GitHub Blog
The Last Watchdog
The Last Watchdog
F
Fortinet All Blogs
S
Schneier on Security
Help Net Security
Help Net Security
Security Archives - TechRepublic
Security Archives - TechRepublic
C
Check Point Blog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
P
Proofpoint News Feed
I
InfoQ
T
The Blog of Author Tim Ferriss
Cisco Talos Blog
Cisco Talos Blog
Stack Overflow Blog
Stack Overflow Blog
T
Troy Hunt's Blog
人人都是产品经理
人人都是产品经理
T
Threatpost
www.infosecurity-magazine.com
www.infosecurity-magazine.com
C
Cyber Attacks, Cyber Crime and Cyber Security
雷峰网
雷峰网
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
爱范儿
爱范儿
Forbes - Security
Forbes - Security
Vercel News
Vercel News
S
Security Affairs
美团技术团队
P
Privacy & Cybersecurity Law Blog
N
News and Events Feed by Topic
Cyberwarzone
Cyberwarzone
Recent Commits to openclaw:main
Recent Commits to openclaw:main
Jina AI
Jina AI
Spread Privacy
Spread Privacy
Attack and Defense Labs
Attack and Defense Labs
IT之家
IT之家
U
Unit 42
Recorded Future
Recorded Future
W
WeLiveSecurity
PCI Perspectives
PCI Perspectives
P
Palo Alto Networks Blog
H
Hacker News: Front Page
S
Security @ Cisco Blogs
博客园 - 【当耐特】

博客园 - Eagletian

修改时间 小结 薪酬管理 小结 小结 小结 管理定律大全 www.shanzei.com ITSM网上资源导航 From:act.it.sohu.com 《IT服务管理:概念、理解与实施》 实战Delphi数据网格色彩特效 自制精美易用的DBGrid from: www.delphifans.com 谁有能让窗体自动适应显示器分辨率的控件? From: www.delphibbs.com Delphi - Stored procedures returning data (MSSQL, Firebird, Oracle) From: http://www.scip.be 图像数据的数据库应用程序 SQL Server存储图像数据的策略与方法 在delphi中获取SQL Server的错误信息初探 我对DELPHI写的几个基类型 From: www.donews.net Delphi 7.0常用函数速查手册 创建Photoshop式浮动窗口应用程序 From:csdn Delphi自定义消息应用一例 From:www.bvtc.com.cn
Delphi分布式系统(MIDAS)中动态调用存储过程 From: www.ccw.com.cn
Eagletian · 2005-02-23 · via 博客园 - Eagletian

一、前言

    现在,多层应用程序已经和其他计算机技术一样越来越多地被谈论。多层应用程序和传统的客户/服务器应用程序相比,前者有更多的优点。而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);设定为第一个参数,才能正常使用。