免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1235 | 回复: 0
打印 上一主题 下一主题

[RAID与磁盘阵列] 如何在Delphi中调用oracle的存储过程返回数据集 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-04-21 09:43 |只看该作者 |倒序浏览
【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 ;


本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u2/66684/showart_570764.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP