在delphi中调用存储过程的时候,怎样返回记录集

如题所述

【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 ;

本人水平有限,如有不当与错误之处请指正!

--------------------------------------------------
问:你好:
看到你的关于DELPHI调用ORACLE存储过程返回结果集的文章,很受触发。
我已经实现了在DELPHI里调用ORACLE存储过程,通过一个游标参数,返回一个结果集的情况。现在有个问题:在存储过程里,可以实现多个弱游标参数输出多个结果集,但是,在DELPHI里,我不知道,怎么取得这第二个或其后的通过游标返回的结果集。通过ADO只能取得第一个结果集。

如果你知道解决方案,请EMAIL联系我。
不胜感激。
答:
用nextrecordset方法就可以了,代码如下:
var
vTemp1:integer;
begin
....
ADODataSet1.Open;
ADODataSet2.Recordset:=ADODataSet1.NextRecordset(vTemp1);
showmessage(ADODataSet2.FieldValues['CID']);
end;

问:怎么连接局域网内的oracle的数据呢?
连接字符串应该怎么写呢?
Provider=OraOLEDB.Oracle.1;Password=KXD;Persist Security Info=True;User ID=KXD;Data Source=TEST3;PLSQLRSet=1
我用的adoquery控件。
答:以下三个参数根据你的情况修改就可以了
Data Source=TNS名称
User ID=用户名
Password=密码
本文来自CSDN博客
温馨提示:内容为网友见解,仅供参考
无其他回答

如何在Delphi中调用oracle的存储过程返回数据集
\/\/下面调用ADODataSet1 的open方法,返回数据集(对应包过程的游标)ADODataSet1.Open ;\/\/根据存储过程,数据集只有一条记录,所以不需要用while do 来遍历数据集,直接取数据了 \/\/此处的字段名根据包过程中的返回游标 对应的字段名来取 \/\/定义的存储过程返回游标如: open ResultCursor for \/\/ ...

如何在Delphi中调用oracle的存储过程返回数据集
\/\/下面调用ADODataSet1 的open方法,返回数据集(对应包过程的游标)ADODataSet1.Open ;\/\/根据存储过程,数据集只有一条记录,所以不需要用while do 来遍历数据集,直接取数据了 \/\/此处的字段名根据包过程中的返回游标 对应的字段名来取 \/\/定义的存储过程返回游标如: open ResultCursor for \/\/ ...

请问高手:在Delphi中怎样调用Oracle中返回结果集的存储过程?
用Delphi的TADOStoreProcedure连接Oracle的存储过程可以执行,我已经用了几次了,只是我的存储过程是在三层中的中间层写的,而且我并没有返回一个数据集,你可以将放回的数据定义称多维数组,返回调用如下:adspRunYtj.Parameters.ParamByName('ny').Value:=NY;

delphi客户端调用存储过程返回参数,请问怎么解决
begin ClientDataSet5.Close;\/\/ FormID、Opid是传入值,doccode是传出值 注意参数不能带@,传出值不要加output,传入、传出类型已在CreateParam时指定了 ClientDataSet5.CommandText := ' Execute _sysP_NewDocCode :FormID,:Opid,:doccode ';ClientDataSet5.Params.Clear;ClientDataSet5.Params.Cre...

在delphi 中怎么利用sql中的存储过程的返回值
存储过程:Create procedure proc_login username varchar(20),password varchar(20)as declare @result int select @result=count(*) from table1 where user=@username and pass=@password if @result=0 return 0 return 1 go delphi代码:var ret:integer;...with ADOStoredProc1 do begin Close;...

为什么delphi中执行存储过程遇到错误就不能返回数据呢?而在查询分析器...
你是不是设置了主键啊 主键重复了吧,你可以SELECT 看下你插入的数据是不是有重复,而且插入的值为主键

delphi 中如何使用sql 存储过程的返回值
写query控件SQL语句的时候这样写:Declare @r int Exec @r = myProc Select @r as result 然后Open,用FieldByNmae读取result字段的值

Delphi中能使用返回多个结果集的存储过程吗
1 如果你要的结果集是一列的,就是只返回一个字段的,可以考虑用Out的字符串参数实现,就是 定义两个Out的String参数,结果集不要太大,数值之间用逗号间隔,这样的好处是可以 Create一个StringList,然后用StringList.CommaText 属性读入处理,还是比较方便的。2 可以TClientData控件建立一个Flate Data...

delphi 如何接住sql 存储过程output传下来的参数
譬如这样一个存储过程 create procedure proc_inserttea(@i int output,@id char(10),@name char(10),@title char(20),@grade char(5))as insert into teacher(Tid,Tname,title,Tgrade) values(@id,@name,@title,@grade)select @i=id from teacher where Tid=@id 传出id这个参数,用...

delphi 调用存储过程
用SQL数据库为例子 代码如下:ADOStoredProc1.Close;DataSource2.DataSet:=ADOStoredProc1;ADOStoredProc1.ProcedureName:='存储过程名称';ADOStoredProc1.Parameters.Refresh; \/\/必须有该条刷新语句 ADOStoredProc1.Parameters[1].Value:=2; \/\/在存储过程组件里参数从1 开始 ADOStoredProc1.ExecProc;ADOStore...

相似回答