首页 > 数据库 > Oracle > 正文

使用OLE DB和ADO调用返回记录集的Oracle存储过程

2024-08-29 13:32:20
字体:
来源:转载
供稿:网友

  摘要 ole db是建立在odbc成功基础上的一种开放规范,它为访问和操纵不同类型数据提供开放的标准。ado是old db的一个消费者,它提供了对ole db数据源应用级的访问功能。在应用程序中使用ole db和ado,可以高效地调用返回记录集的oracle存储过程。

  关键字 ole db ado 存储过程 记录集

  1 前言

  在基于oracle数据库的ado应用程序的开发过程中,为了提高执行速度和降低网络流量,往往要在应用程序中调用oracle数据库服务器端的存储过程。有的存储过程需要返回多行的记录集。这种情况下,在应用程序中调用返回记录集的存储过程存在一定的难度。本文介绍如何使用ole db和ado调用返回记录集的oracle存储过程。

  2 ole db和ado的关系

  2.1 ole db简介

  ole db建立在odbc成功基础上的开放的规范,它为访问和操纵不同类型数据提供开放的标准。ole db定义了一个com接口集合,它封装了各种数据库管理系统服务。这些接口允许创建实现这些服务的软件组件。ole db组件包括数据提供者(存储和发布数据)、数据消费者(使用数据)和服务组件(处理和传输数据)。

  ole db的设计是以消费者和提供者概念为中心。ole db消费者表示传统的客户方,提供者将数据以表格形式传递给消费者。ole db的oracle提供者(oraoledb)可使ole db消费者高效地访问oracle数据源。图1给出ole db的系统图示。ole db数据提供者将数据从数据源传递给消费者。在标准接口的基础上,ole db消费者能够访问来自提供者的数据。因为有com组件,消费者可以用任何支持com的编程语言访问数据。

  2.2 ado对象模在ado对象模型中,connection、command和recordset对象是三个主要的对象。connection对象表示对远程数据的连接。connection对象可与command对象或recordset对象关联。command对象定义了对数据源执行的指定命令。command对象可以用来执行命令和参数化的sql语句,可以用于sql语句和返回记录集的sql查询。command对象既可以使用一个活动的connection对象,也可以创建它自己到目标数据源的连接。command对象包含一个parameters集合,在该集合中每一个parameter对象表示command对象使用的参数。command对象执行参数化的sql语句时,每一个parameter对象表示sql语句中的一个参数。recordset对象表示的来自基本表或命令执行结果的记录全集。recordset对象既可以使用一个活动的connection对象,也可以创建它自己到目标数据源的连接。recordset对象允许查询和修改数据。每一个recordset包含一个field对象集合,其中,每个field对象表示recordset中一个数据列。

|||

  2.3 ado和ole db的关系

  ole db是系统级编程接口,ado是应用软件级编程接口。ado是ole db的一个消费者,它提供了对ole db数据源应用级的访问功能。ado为ole db提供了一个易于使用的应用级接口。ado允许用户编写通过ole db提供者对数据库服务器中的数据进行访问和操作的应用程序。其主要的优点是易于使用、高速度、低内存和占用较少的磁盘空间。ado和ole db的关系如图2所示:

  3 oracle中返回记录集的存储过程的定义

  在oracle存储过程中,通过定义类型为ref cursor(游标指针)的传出参数,可以返回记录集。ole db允许消费者执行带ref cursor类型参数的pl/sql存储过程,或者执行返回ref cursor的存储函数。返回记录集的存储过程或函数必须定义在程序包里。包是oracle数据库的一种对象,它可以将数据类型、存储过程、函数、变量和常量封装在一起。包在结构上分为包头和包体两部分,这两部分要分别建立。包头用来定义可被外部引用的元素;包体定义实际代码。使用程序包定义返回记录集的存储过程时,需要在包头中预定义自己的ref cursor类型。在程序包体中,存储过程或函数须使用预定义的游标类型。另外,在一个存储过程或函数中,可以定义多个ref cursor类型的参数以返回多个记录集。

  以下以职工表emp为例,介绍如何定义返回记录集的oracle存储过程,emp表的定义如下:

create table emp(
empno number(4) not null, --职工编号
ename varchar2(10), --职工姓名
hiredate date, --雇佣日期
sal number(7,2), --工资
deptno number(2)); --所属部门编号

  下面给出返回记录集的oracle存储过程和存储函数的示例程序包头和包体,其中存储过程getemprecords含有两个ref cursor类型的传出参数,返回两个记录集,存储函数getdept的返回值类型为ref cursor,返回一个记录集。

|||,欢迎访问网页设计爱好者web开发。--定义一个名为employees的程序包头
create or replace package employees as
type empcur is ref cursor;
--empcur为自定义ref cursor类型
--声明一个存储过程getemprecords
procedure getemprecords(p_cursor out empcur,
q_cursor out empcur,
indeptno in number,
p_errorcode out number);
--声明一个存储函数getdept
function getdept(inempno in number,
p_errorcode out number)
return empcur;
end employees; ---程序包头定义结束
--定义employees的程序包体
--定义存储过程getemprecords
create or replace package body employees as procedure getemprecords(p_cursor out empcur, q_cursor out empcur,
indeptno in number, p_errorcode out number) is
begin
p_errorcode := 0; -- p_errorcode为错误编号
--打开游标变量p_cursor,查询所属部门编号
--为indeptno的所有职工的信息
open p_cursor for
select * from emp
where deptno = indeptno order by empno;
--打开游标变量q_cursor,查询所属部门编号
--为indeptno的所有职工的编号信息
open q_cursor for
select empno from emp
where deptno = indeptno order by empno;
exception --例外处理
when others then
p_errorcode:= sqlcode;
end getemprecords; --存储过程getemprecords定义结束
--定义存储函数getdept
function getdept(inempno in number,
p_errorcode out number)
return empcur is p_cursor empcur; --返回值
begin
p_errorcode := 0;

  --查询职工编号为inempno的职工的所属部门编号

|||

  open p_cursor for

  select deptno from emp where empno = inempno;

  return (p_cursor);

  exception

  when others then

  p_errorcode:= sqlcode;

  end getdept;

  end employees; --程序包体定义结束

  4 利用ado调用返回记录集的oracle存储过程

  使用ole db和ado调用返回记录集的oracle存储过程,在定义ado对象和设置参数时,需要特定的设置。

  4.1 设定数据库连接字符串

  在ado应用程序中,如果要访问返回记录集的oracle存储过程,需要使用oraole db的数据库连接字符串的指定格式。在连接字符串中,plsqlrset属性表明oraole db是否需要从pl/sql存储过程返回记录集。如果需要返回记录集,plsqlrset设为1,否则设置为0,默认为 0。在command命令执行后,该属性需要设置为0。

  4.2 参数的设置

  在ado应用程序中,可以定义调用存储过程的参数。可使用command对象的createparameter 方法创建parameter 对象,并使用 append 方法将它们添加到 parameters 集合,在调用存储过程时,parameters 集合将参数传递给存储过程。由于oraole db采用定位传递参数的格式,即command对象在调用存储过程时,调用参数的位置应和存储过程的参数的位置相对应。根据调用的存储过程的参数属性、名称和位置,在ado中, append 方法添加参数的次序应和存储过程中参数的顺序一致。

  在ole db的标准中,没有ref cursor类型的预定义数据类型,因此在调用存储过程时,不能创建ref cursor类型的参数。在ado调用返回记录集的存储过程时,ole db自动为存储过程中ref cursor类型的传出参数返回记录集,该记录集可以赋值给一个recordset对象。如果pl/sql存储过程有一个或多个ref cursor类型的传出参数,ole db将这些参数的记录集集成在一起,并通过第一个ref cursor类型的传出参数返回,这些记录集同样可以赋值给一个recordset对象。

|||

  4.3 调用存储过程的格式

  调用返回记录集存储过程之前,应将command对象的 commandtype 属性指定sql类型以优化查询性能,即commandtype 属性值设为adcmdtext。

  使用 command对象的commandtext 属性定义调用存储过程的命令。当使用command对象执行oracle返回记录集存储过程时,须以odbc转义符调用格式来调用存储过程,例如:{call credit_account(?,?)}。在这种格式中,传入和传出参数都用问号“?”来表示。

  4.4返回记录集

  可使用command对象的 execute 方法调用oracle返回记录集的存储过程,并在适当的时候将结果记录集返回给 recordset对象。该对象可以存储一个或多个结果记录集。当存储多个记录集时,可以用recordset对象的nextrecordset属性获得下一个记录集。

  下面给出在asp中调用返回存储过程或函数的示例程序:

<%@ language=vbscript %>
<!--#include file="adovbs.inc"-->
<%
'connection 对象代表了打开的、与数据源的连接。
set con=server.createobject("adodb.connection")
set rst1 =server.createobject("adodb.recordset")
set rst2=server.createobject("adodb.recordset")
set cmd =server.createobject("adodb.command")
set prm1 =server.createobject("adodb.parameter")
set prm2 =server.createobject("adodb.parameter")
con.provider = "oraoledb.oracle" '设置ole db提供者
'设置数据库连接字符串,test是数据库网络服务名
con.connectionstring = "data source=test;" & _
"user id=scott;password=tiger;plsqlrset=1"
'调用返回记录集的存储过程,plsqlrset指定为1
con.open
'创建command对象到目标数据源的连接
cmd.activeconnection = con
cmd.commandtype=adcmdtext
'虽然employees.getemprecords()有四个参数,
'但只有需要设定两个参数
'因为ref cursor参数由ole db连接提供者自动设定。
set prm1 = cmd.createparameter("prm1", adsmallint, adparaminput, , 30) '创建一个输入参数,对应于indeptno
cmd.parameters.append prm1 '将参数添加到参数集合中
set prm2 = cmd.createparameter("prm2", adsmallint, adparamoutput) '创建一个输出参数,对应于p_errorcode
cmd.parameters.append prm2
'调用返回记录集的存储过程必须使用odbc的转义符调用格式。
cmd.commandtext = "{call employees.getemprecords(?, ?)}"
'getemprecords存储过程返回两个记录集,获得第一个记录集
set rst1 = cmd.execute %>
<table border = 1>
<%
do while (not rst1.eof) %>
<tr>
<% for index=0 to (rst1.fields.count-1) %>
<td valign=top><% = rst1(index)%></td>
<% next %>
</tr>
<% rst1.movenext
loop '显示第一个记录集
%>
</table>
<%'获得getemprecords存储过程返回的第二个记录集
set rst2 = rst1.nextrecordset
'在此可加入显示第二个记录集的代码
prm1.value = 7369 '该参数对应于存储函数的inempno
prm2.value = 0 '该参数对应于存储函数的p_errorcode
'调用返回记录集的存储函数
cmd.commandtext = "{call employees.getdept(?, ?)}"
'获得getdept存储函数返回的记录集
set rst2 = cmd.execute
rst1.close
rst2.close
set rst1=nothing
set rst2=nothing
con.close
set con=nothing
%>
<p> </p>
</body>
</html>

  5 小结

  在应用程序中,使用ole db和ado访问返回记录集的存储过程,ole db服务者可以高效地将数据库端的多行记录集返回给ado应用程序。在ado应用程序中,使用command对象可以传递输入或输出参数给存储过程,并调用存储过程以获得多行记录集。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表