delphi中调用oracle的存储过程.docx
《delphi中调用oracle的存储过程.docx》由会员分享,可在线阅读,更多相关《delphi中调用oracle的存储过程.docx(5页珍藏版)》请在冰豆网上搜索。
delphi中调用oracle的存储过程
【delphi+oracle报表解决方案
(一)】delphi中调用oracle的存储过程(分带返回游标,不返回值两种)
关键字:
delphi,oracle存储过程,游标,返回数据集,报表
注:
delphi6+oracle8.1.6
一.创建包与包体
1.附:
建表aaclass为下面作测试用
createtableaaclass(CIDVARCHAR2(50),CNAMEVARCHAR2(50),pnumberNUMBER(10,0));
INSERTINTOaaclassvalues('c1','cn1',10);
INSERTINTOaaclassvalues('c2','cn2',40);
INSERTINTOaaclassvalues('c1','cn3',30);
commit;
2.建包:
CREATEORREPLACE PACKAGEPKG_JCCTEST1
AS
typerc_classisrefcursor;
--求p1,p2的和与差,返回的多个值通过游标返回
procedureGetSubAndSum2(p1number,p2 number,
ResultCursoroutrc_class);
--查询满足条件的数据集,返回数据集通过游标返回
procedureGetClass2(ainnumber,ResultCursoroutrc_class);
--往表中插一条记录,不返回结果集时,本人用AdoQuery调用(adodataset好象要求必须返回结果集)
procedureInsertClass(p_cidvarchar2,p_cnamevarchar2,
p_pnumbernumber);
endPKG_JCCTEST1;
3.建包体
CREATEORREPLACE PACKAGEBODYPKG_JCCTEST1
AS
procedureGetSubAndSum2(p1number,p2 number,
ResultCursoroutrc_class)
IS
BEGIN
openResultCursorfor
selectp1-p2as"sum",p1+p2as"sub"fromdual;
END;
procedureGetClass2(ainnumber,ResultCursoroutrc_class)
is
begin
openResultCursorfor
selectaaclass.*fromaaclasswherepnumber>a;
end;
procedureInsertClass(p_cidvarchar2,p_cnamevarchar2,
p_pnumbernumber)
is
begin
insertintoaaclassvalues(p_cid,p_cname,p_pnumber);
-- commit;
end;
二.在delphi中利用AdoDataSet调用上述第一个存储过程
1.利用AdoConnection1连接数据库(驱动为oracleProviderforOLEDB),
**并在连接字符串中加入这一节:
PLSQLRSet=1;如下所示:
Provider=OraOLEDB.Oracle.1;Password=KXD;PersistSecurityInfo=True;UserID=KXD;DataSource=TEST3;PLSQLRSet=1
2.在窗体上加AdoDataSet1指明连接为上述AdoConnection1,下面可以放一个按钮,单击按钮就能调用第一步中创建的包过程,并返回数据集。
代码如下所示:
procedureTForm1.Button1Click(Sender:
TObject);
var
AResult,BResult:
integer;
begin
ADODataSet1.Close;
ADODataSet1.CommandType:
= cmdText;
ADODataSet1.Parameters.Clear;
//***利用call方法调用oracle过程时,参数必须由?
来传,即使你要传的参数为常理
//输出游标的参数不需要指定!
!
!
!
!
!
,本来此函数带三个参数,我们这里只需要传两个参数.
ADODataSet1.CommandText:
='{callPKG_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;
//根据存储过程,数据集只有一条记录,所以不需要用whiledo来遍历数据集,直接取数据了
//此处的字段名根据包过程中的返回游标对应的字段名来取
//定义的存储过程返回游标如:
openResultCursorfor
// selectp1-p2as"sum",p1+p2as"sub"fromdual;
//把对应的字段值取出来即可
AResult:
=ADODataSet1.Fields.FieldByName('sub').Value;
BResult:
=ADODataSet1.Fields.FieldByName('sum').Value;
//显示结果
showmessage(inttostr(AResult));
showmessage(inttostr(BResult));
end;
三.在delphi中利用AdoDataSet调用上述第二个存储过程
还是利用上述的AdoDataSet1来调用第二个存储过程,无需任何改动,加第二个按钮,单击时代码如下:
procedureTForm1.Button2Click(Sender:
TObject);
begin
ADODataSet1.Close;
ADODataSet1.CommandType:
= cmdText;
ADODataSet1.Parameters.Clear;
//***利用call方法调用oracle过程时,参数必须由?
来传,即使你要传的参数为常理
//输出游标的参数不需要指定!
!
!
!
!
!
,本来此函数带两个参数,我们这里只需要传一个参数.
ADODataSet1.CommandText:
='{callPKG_JCCTEST1.GetClass2(?
)}';
//***C顺序有关,createparam必须放在commandtext赋值语句之后.
//创建第一个参数,对应call中的第一个?
ftinteger为类型,10为长度,20为传入的实参值
ADODataSet1.Parameters.CreateParameter('p1',ftinteger,pdinput,10,20);
//下面调用ADODataSet1的open方法,返回数据集(对应包过程的游标)
ADODataSet1.Open;
whilenotADODataSet1.Eofdo
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调用第三个过程,不返回数据集的
procedureTForm1.Button3Click(Sender:
TObject);
begin
AdoQuery1.Close;
AdoQuery1.Parameters.Clear;
AdoQuery1.SQL.Clear;
AdoQuery1.SQL.Add('{callPKG_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调用第一个过程,返回数据集的.
procedureTForm1.Button4Click(Sender:
TObject);
begin
AdoQuery1.Close;
AdoQuery1.Parameters.Clear;
AdoQuery1.SQL.Clear;
AdoQuery1.SQL.Add('{callPKG_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:
='{callPackageName.ProcedureName(?
?
)}';
ClientDataSet1.Params.CreateParam(ftInteger,'ParamName1',ptInput);
ClientDataSet1.Open;
end;