如何在Delphi中调用oracle的存储过程返回数据集(转)

如何在Delphi中调用oracle的存储过程返回数据集,sql,sql教程,Oracle基础

选自CSDN http://search.csdn.net/Expert/topic/2280/2280860.xml?temp=2.169436E-02 论坛中JCC0128 网友的发言

【delphi+oracle报表解决方案(一)】delphi中调用oracle的存储过程(分带返回游标 不返回值两种)
关键字: delphi ,oracle存储过程 游标,返回数据集,报表

注:delphi 6+ oracle 8.1.6

一.创建包与包体

1.附:建表aaclass为下面作测试用

create table aaclass(CID VARCHAR2(50), CNAME VARCHAR2(50), pnumber NUMBER(10,0) );

INSERT INTO aaclass values('c1', 'cn1', 10 ) ;
INSERT INTO aaclass values('c2', 'cn2', 40 ) ;
INSERT INTO aaclass values('c1', 'cn3', 30 ) ;
commit;

2.建包:

CREATE OR REPLACE PACKAGE PKG_JCCTEST1
AS

type rc_class is ref cursor;


--求p1,p2的和与差 返回的多个值通过游标返回
procedure GetSubAndSum2(p1 number,p2 number ,
ResultCursor out rc_class);

--查询满足条件的数据集 返回数据集通过游标返回
procedure GetClass2(a in number,ResultCursor out rc_class ) ;

--往表中插一条记录 不返回结果集时 本人用AdoQuery调用(adodataset好象要求必须返回结果集)
procedure InsertClass( p_cid varchar2 ,p_cname varchar2 ,
p_pnumber number) ;
end PKG_JCCTEST1;



3.建包体

CREATE OR REPLACE PACKAGE BODY PKG_JCCTEST1
AS

procedure GetSubAndSum2(p1 number,p2 number ,
ResultCursor out rc_class)
IS
BEGIN
open ResultCursor for
select p1-p2 as "sum", p1+p2 as "sub" from dual;
END ;


procedure GetClass2(a in number,ResultCursor out rc_class )
is
begin

open ResultCursor for
select aaclass.* from aaclass where pnumber >a;

end ;

procedure InsertClass( p_cid varchar2 ,p_cname varchar2 ,
p_pnumber number)
is
begin
insert into aaclass values(p_cid,p_cname,p_pnumber) ;
-- commit;
end ;





二.在delphi中利用AdoDataSet调用上述第一个存储过程
1.利用AdoConnection1连接数据库(驱动为 oracle Provider for OLE DB)
**并在连接字符串中加入这一节: PLSQLRSet=1; 如下所示:
Provider=OraOLEDB.Oracle.1;Password=KXD;Persist Security Info=True;User ID=KXD;Data Source=TEST3;PLSQLRSet=1

2.在窗体上加AdoDataSet1 指明连接为上述AdoConnection1,下面可以放一个按钮 单击按钮就能调用第一步中创建的包过程 并返回数据集 代码如下所示:


procedure TForm1.Button1Click(Sender: TObject);
var
AResult , BResult : integer;
begin
ADODataSet1.Close ;
ADODataSet1.CommandType := cmdText ;
ADODataSet1.Parameters.Clear ;

//***利用call方法调用oracle过程时 参数必须由?来传 即使你要传的参数为常理
//输出游标的参数不需要指定!!!!!! 本来此函数带三个参数 我们这里只需要传两个参数.
ADODataSet1.CommandText := '{call PKG_JCCTEST1.GetSubAndSum2(?,?)}' ;

//***C 顺序有关 createparam必须放在commandtext赋值语句之后.

// 创建第一个参数 对应call中的第一个?,ftinteger为类型,10为长度 45为传入的实参值
ADODataSet1.Parameters.CreateParameter('p1',ftinteger,pdinput,10,45);
//创建第二个参数 根据createparameter的顺序 自动与call中的第二个参数对应
ADODataSet1.Parameters.CreateParameter('p2',ftinteger,pdinput,10,4);

//下面调用ADODataSet1 的open方法 返回数据集(对应包过程的游标)
ADODataSet1.Open ;

//根据存储过程 数据集只有一条记录 所以不需要用while do 来遍历数据集 直接取数据了

//此处的字段名根据包过程中的返回游标 对应的字段名来取
//定义的存储过程返回游标如: open ResultCursor for
// select p1-p2 as "sum", p1+p2 as "sub" from dual;
//把对应的字段值取出来即可
AResult := ADODataSet1.Fields.FieldByName('sub').Value ;
BResult := ADODataSet1.Fields.FieldByName('sum').Value ;

//显示结果
showmessage(inttostr(AResult)) ;
showmessage(inttostr(BResult)) ;

end;




三.在delphi中利用AdoDataSet调用上述第二个存储过程


还是利用上述的AdoDataSet1来调用第二个存储过程 无需任何改动,加第二个按钮 单击时代码如下:

procedure TForm1.Button2Click(Sender: TObject);
begin
ADODataSet1.Close ;
ADODataSet1.CommandType := cmdText ;
ADODataSet1.Parameters.Clear ;

//***利用call方法调用oracle过程时 参数必须由?来传 即使你要传的参数为常理
//输出游标的参数不需要指定!!!!!! 本来此函数带两个参数 我们这里只需要传一个参数.
ADODataSet1.CommandText := '{call PKG_JCCTEST1.GetClass2(?)}' ;

//***C 顺序有关 createparam必须放在commandtext赋值语句之后.

// 创建第一个参数 对应call中的第一个?,ftinteger为类型,10为长度 20为传入的实参值
ADODataSet1.Parameters.CreateParameter('p1',ftinteger,pdinput,10,20);


//下面调用ADODataSet1 的open方法 返回数据集(对应包过程的游标)
ADODataSet1.Open ;

while not ADODataSet1.Eof do
begin
showmessage('CID : '+string(ADODataSet1.FieldByName('CID').Value) +
'--CNAME :' + string(ADODataSet1.FieldByName('CNAME').Value) +
'--PNUMBER :' + string(ADODataSet1.FieldByName('PNUMBER').Value)
) ;
ADODataSet1.Next ;
end ;
end;





四 利用adoquery调用第三个过程 不返回数据集的

procedure TForm1.Button3Click(Sender: TObject);
begin
AdoQuery1.Close ;
AdoQuery1.Parameters.Clear ;

AdoQuery1.SQL.Clear ;

AdoQuery1.SQL.Add('{call PKG_JCCTEST1.GetSubAndSum2(?,?)}') ;
AdoQuery1.Parameters.CreateParameter('P1',ftstring,pdinput, 50,'c11') ;
AdoQuery1.Parameters.CreateParameter('P2',ftstring,pdinput, 50,'cn11') ;
AdoQuery1.Parameters.CreateParameter('P3',ftinteger,pdinput, 50,25) ;

AdoQuery1.ExecSQL ;
end;


五 利用adoquery调用第一个过程 返回数据集的.


procedure TForm1.Button4Click(Sender: TObject);
begin
AdoQuery1.Close ;
AdoQuery1.Parameters.Clear ;

AdoQuery1.SQL.Clear ;

AdoQuery1.SQL.Add('{call PKG_JCCTEST1.GetSubAndSum2(?,?)}') ;
AdoQuery1.Parameters.CreateParameter('P1',ftinteger,pdinput, 50,25) ;
AdoQuery1.Parameters.CreateParameter('P2',ftinteger,pdinput, 50,22) ;

AdoQuery1.Open ;

Showmessage(string( AdoQuery1.FieldByName('sub').Value)+'-'+
string( AdoQuery1.FieldByName('sum').Value));
end;

六.关于三层体系的此类问题

两层的解决了 三层类似.
中间层用tadodataset 或tadoquery (+tdatasetprovider),中间层的adoconnection的连接字符串加上plsqlRset=1;
客户端用clientdataset ,大同小异 举例如下:

begin
//调用相应的过程
ClientDataSet1.Close ;
ClientDataSet1.Params.Clear ;

ClientDataSet1.CommandText := '{call PackageName.ProcedureName(?,?)}' ;
ClientDataSet1.Params.CreateParam(ftInteger , 'ParamName1', ptInput) ;
ClientDataSet1.Open ;

end ;

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/10294527/viewspace-122219/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/10294527/viewspace-122219/

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值