Oracle集合类型输出参数的PLSQL存储过程及其Java.doc_第1页
Oracle集合类型输出参数的PLSQL存储过程及其Java.doc_第2页
Oracle集合类型输出参数的PLSQL存储过程及其Java.doc_第3页
Oracle集合类型输出参数的PLSQL存储过程及其Java.doc_第4页
Oracle集合类型输出参数的PLSQL存储过程及其Java.doc_第5页
已阅读5页,还剩5页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

Oracle集合类型输出参数的PL/SQL存储过程及其Java调用- - 有段时间为了用存储过程做统计报表,写了这文章。现在的java的数据库-关系映射技术似乎不提倡用存储过程,其实存储过程更能发挥数据库的效率。1 引言存储过程因其执行效率高、与事务处理的结合、运行更安全等优点,在数据库应用程序中被广泛采用。PL/SQL是用于从各种环境中访问Oracle数据库的一种编程语言,它与数据库服务器集成在一起,PL/SQL编写的存储过程编译效率高,网络系统开销小,同时PL/SQL直观性好,是大多数人的选择。以Number、Varchar等基本标量类型为输出参数的PL/SQL存储过程,每个输出参数只能返回一个对应值。而在实际数据库应用程序中,尤其是在进行系统综合查询统计时,往往需要返回二维数组或结果集,这时应考虑在存储过程中使用集合这种数据结构。对于集合,我们可以一次把许多元素作为一个整体进行操作,也可以对集合中的单个元素进行操作,使用方便、灵活。2 PL/SQL存储过程及Java程序的编写2.1 索引表作为输出参数索引表是无约束的,其大小的唯一限制(除可用内存外)就是它的关键字BINARY_INTEGER类型所能表示数值的约束(-2147483647.+2147483647),其元素不需要按任何特定顺序排列。在声明时,我们不需要指定其大小,而且对索引表的元素可以直接赋值,不用初始化,可见使用索引表极其方便。2.1.1存储过程的编写我们可以在PL/SQL语句块中定义索引表,但作为输出参数的索引表,必须要在包(package)里定义,方法如下:create or replace package out_param is - 定义了元素是varchar2类型的一个索引表类型type out_index_table_typ is table of varchar2(50) index by binary_integer;end out_param;接下来就可以在pl/sql存储过程里引用在包里定义的索引表类型: create or replace procedure testPro1(in_param in varchar2,o_table out out_param. out_index_table_typ ) is begin -这里略去程序体 end testPro1; 其中,返回的索引表类型前必须用包名加上句点来引用out_param. out_index_table_typ 2.1.2 Java程序的编写索引表与数据库表很形似,有key和value两列,但它不是真正的数据库表,不可以存储到数据库中。因此索引表不能使用SQL进行操作,这样它的内容不能通过一个标准的SELECT语句返回游标得到。这一点与嵌套表有很大不同。由存储过程返回的索引表可以映射成java数组类型、JDBC Datatypes的BigDecimal数组类型和oracle的Datum数组。有一点要注意,尽管索引表中的元素不一定要按任何特定顺序排列,其元素可以借助于任意有效关键字而插入,但对映射数组元素的引用应该从1开始,而且要连续,否则映射成数组时会出现null元素。下面示例为将索引表映射成java数组类型。import oracle.jdbc.*;import oracle.sql.*;import java.sql.*;public class ReturnIndexTable Connection ociconn=null;OracleCallableStatement stmt =null;public String getTable(String in_param) String reAry=null;try OracleDriver S_Driver=null;if(S_Driver=null)S_Driver=new oracle.jdbc.OracleDriver();DriverManager.registerDriver(S_Driver);String url=jdbc:oracle:oci8:test;String user=user;String password= password;ociconn= DriverManager.getConnection(url,user,password);stmt =(OracleCallableStatement)ociconn.prepareCall(begin testPro1(?,?); end;);/ 返回的索引表最大长度(可以大于索引表实际长度)int maxLen =31;/ 索引表元素类型int elemSqlType = OracleTypes.VARCHAR;/索引表元素长度(CHAR, VARCHAR or RAW),其它元素类型可忽略该项值,但该参数仍须定义int elemMaxLen=50;stmt.setString(1,in_param);/ 注册返回参数stmt.registerIndexTableOutParameter(2,maxLen,elemSqlType,elemMaxLen);stmt.execute();/ 返回数组类型reAry=(String)stmt.getPlsqlIndexTable(2);catch (Exception e)e.printStackTrace();finallyreturn reAry;/关闭连接.2.2 可变数组作为输出参数可变数组和另外两种集合类型不同,其元素在内存中是连续存储的,且在大小方面有一个固定的上界。声明时需要指定该数组中元素的最大数目(可变数组的大小可以用EXTEND方法来增加,但不能被扩展超过所声明的极限大小)。可变数组的元素被赋值之前,必须使用构造器进行初始化。元素插入数组时应从索引1开始,连续插入。2.2.1 存储过程的编写可变数组的定义方法如下:create or replace type testArray is varray(5) of number(3) PL/SQL存储过程里调用可变数组作为输出参数:create or replace function getTestArray return testArrayaso_data testArray:= testArray (); begin for v_count in 1.5 loop o_data.extend; o_data(v_count):= v_count; end loop;return o_data;end; 2.2.2 Java程序的编写 由存储过程返回的可变数组同样可以映射成java数组类型。但Java程序调用存储过程返回的可变数组方式和索引表方式却不相同,这一点应注意,具体方法如下:public static void main( ) ./调用存储过程. OracleCallableStatement stmt =(OracleCallableStatement)conn.prepareCall ( begin ? := getTestArray; end; ); stmt.registerOutParameter( 1, OracleTypes.ARRAY, testArray ); stmt.executeUpdate(); / 得到 ARRAY 对象 ARRAY simpleArray = stmt.getARRAY(1);/转换为java数组 String values = (String)simpleArray.getArray();/输出数组内容 for( int i = 0; i values.length; i+ ) System.out.println( row + i + = + valuesi + );2.3 嵌套表作为输出参数存 储过程中使用嵌套表,并不是直接将嵌套表作为输出参数,而是对嵌套表造型后以游标形式输出。嵌套表的基本功能与索引表相同,但嵌套表可以使用SQL进 行操作,其内容可通过SELECT 语句查询并造型后以游标形式返回。在大多数的查询统计中,常常需要返回结果集,这时使用嵌套表就尤其方便。笔者在开发过程中深刻体会到使用对象嵌套表 可以解决绝大多数的查询统计问题。下面着重介绍如何在存储过程里利用对象类型的嵌套表。对于任意的统计分析表格,我们可以将其简化成下面的输出形式: 统计项目1统计项目2统计项目3统计项目4名称1名称2这样我们把每一行看作是一个对象实例,该行的每一列则可以看作是该对象的一个属性,下面通过构造对象,然后对包含对象的嵌套表进行造型,返回游标得到结果集。2.3.1 存储过程的编写 首先构造统计对象如下: create or replace type TestObj as object( vname varchar2(20), -名称item1 number, -统计项目1item2 number, -统计项目2item3 number, -统计项目3item4 number -统计项目4);构造包含对象类型的嵌套表:create or replace type TestNestTable as table of TestObj;定义对索引表造型后的输出的游标类型:create or replace package out_param is type out_cur is ref cursor; 下面是嵌套表作为输出参数的存储过程:create or replace procedure testPro2(o_cur out out_param.out_cur ) is- 包含对象的嵌套表变量的声明v_objTable TestNestTable:= TestNestTable ();begin -嵌套表变量的使用v_objTable.extend;v_objTable(1):= TestObj(张三,12,123,123,34);v_objTable.extend;v_objTable(2):= TestObj(李四,22,223,223,234);-对嵌套表进行造型返回游标open o_cur for select * from Table(cast (v_objTable as TestNestTable) ); end testPro2;2.3.2 Java程序的编写 /从游标返回结果集public ResultSet getCursor()try.stmt =(CallableStatement )conn.prepareCall(call testPro2(?);/注册游标对象类型stmt.registerOutParameter(1,OracleTypes.CURSOR);stmt.execute();/返回结果集ResultSet Rs=(ResultSet)stmt.getObject(1);catch(Exception e)return Rs;3 结束语使用索引表和可变数组,可将返回的集合映射成Java数组。由于索引表会自动分配空间,在声明时不需要指定其大小,而且不需要初始化,使用起来比较方便。但是索引表作为输出参数只能使用oci驱动(返回游标时,可以用瘦客户驱动也可以用oci驱动),所需要的动态连接库文件(ocijdbc9.dll)要在环境变量里进行设置(例如:path=D:oracleora90BIN),在不同的环境下OCI驱动还可能出现类装载异常,所以返回索引表尽管方便,但偶尔会出现意想不到的错误。可变数组映射成Java数组简单,对于返回小数据量的结果,也是不错的选择,但使用可变数组作为输出参数,声明时必须限定该数组的大小上限,并且需使用构造器初始化。使用嵌套表,可以对嵌套表进行SQL操作,其内容能通过对标准的SELECT 语句造型后可转化为游标输出。而且嵌套表的内容相当于session变量,当断开连接后即释放内存,但同样存在需要初始化和扩展的问题。综 上所述,究竟采用索引表、嵌套表和可变数组中哪一种作为存储过程的输出要看具体的要求和开发环境。有一点我们需要注意,如果返回的数据量较大,以数组形式 返回,则需一次性取回所有结果,在PL/SQL里为所有结果分配空间并复制,然后将这些数据通过网络发送到客户端,客户端也同样需要分配空间接受这些数 据;而采用游标形式,只要返回一个指针,然后分批返回结果(可自定义每次返回记录的条数),而不是一次性返回所有结果,因此在客户端不需分配大块的空间存 放所有结果。可见,对于大数据量的应用程序,返回游标程序运行效率会更高。 Oracle集合类型输出参数的PL/SQL存储过程及其Java调用1 引言存储过程因其执行效率高、与事务处理的结合、运行更安全等优点,在数据库应用程序中被广泛采用。PL/SQL是用于从各种环境中访问Oracle数据库的一种编程语言,它与数据库服务器集成在一起,PL/SQL编写的存储过程编译效率高,网络系统开销小,同时PL/SQL直观性好,是大多数人的选择。以Number、Varchar等基本标量类型为输出参数的PL/SQL存 储过程,每个输出参数只能返回一个对应值。而在实际数据库应用程序中,尤其是在进行系统综合查询统计时,往往需要返回二维数组或结果集,这时应考虑在存储 过程中使用集合这种数据结构。对于集合,我们可以一次把许多元素作为一个整体进行操作,也可以对集合中的单个元素进行操作,使用方便、灵活。2 PL/SQL存储过程及Java程序的编写2.1 索引表作为输出参数索引表是无约束的,其大小的唯一限制(除可用内存外)就是它的关键字BINARY_INTEGER类型所能表示数值的约束(-2147483647.+2147483647),其元素不需要按任何特定顺序排列。在声明时,我们不需要指定其大小,而且对索引表的元素可以直接赋值,不用初始化,可见使用索引表极其方便。2.1.1存储过程的编写我们可以在PL/SQL语句块中定义索引表,但作为输出参数的索引表,必须要在包(package)里定义,方法如下:create or replace package out_param is - 定义了元素是varchar2类型的一个索引表类型type out_index_table_typ is table of varchar2(50) index by binary_integer;end out_param;接下来就可以在pl/sql存储过程里引用在包里定义的索引表类型: create or replace procedure testPro1(in_param in varchar2,o_table out out_param. out_index_table_typ ) is begin -这里略去程序体 end testPro1; 其中,返回的索引表类型前必须用包名加上句点来引用out_param. out_index_table_typ 2.1.2 Java程序的编写索引表与数据库表很形似,有key和value两列,但它不是真正的数据库表,不可以存储到数据库中。因此索引表不能使用SQL进行操作,这样它的内容不能通过一个标准的SELECT语句返回游标得到。这一点与嵌套表有很大不同。由存储过程返回的索引表可以映射成java数组类型、JDBC Datatypes的BigDecimal数组类型和oracle的Datum数组。有一点要注意,尽管索引表中的元素不一定要按任何特定顺序排列,其元素可以借助于任意有效关键字而插入,但对映射数组元素的引用应该从1开始,而且要连续,否则映射成数组时会出现null元素。下面示例为将索引表映射成java数组类型。import oracle.jdbc.*;import oracle.sql.*;import java.sql.*;public class ReturnIndexTable Connection ociconn=null;OracleCallableStatement stmt =null;public String getTable(String in_param) String reAry=null;try OracleDriver S_Driver=null;if(S_Driver=null)S_Driver=new oracle.jdbc.OracleDriver();DriverManager.registerDriver(S_Driver);String url=jdbc:oracle:oci8:test;String user=user;String password= password;ociconn= DriverManager.getConnection(url,user,password);stmt =(OracleCallableStatement)ociconn.prepareCall(begin testPro1(?,?); end;);/ 返回的索引表最大长度(可以大于索引表实际长度)int maxLen =31;/ 索引表元素类型int elemSqlType = OracleTypes.VARCHAR;/索引表元素长度(CHAR, VARCHAR or RAW),其它元素类型可忽略该项值,但该参数仍须定义int elemMaxLen=50;stmt.setString(1,in_param);/ 注册返回参数stmt.registerIndexTableOutParameter(2,maxLen,elemSqlType,elemMaxLen);stmt.execute();/ 返回数组类型reAry=(String)stmt.getPlsqlIndexTable(2);catch (Exception e)e.printStackTrace();finallyreturn reAry;/关闭连接.2.2 可变数组作为输出参数 可变数组和另外两种集合类型不同,其元素在内存中是连续存储的,且在大小方面有一个固定的上界。声明时需要指定该数组中元素的最大数目(可变数组的大小可以用EXTEND方法来增加,但不能被扩展超过所声明的极限大小)。可变数组的元素被赋值之前,必须使用构造器进行初始化。元素插入数组时应从索引1开始,连续插入。2.2.1 存储过程的编写可变数组的定义方法如下:create or replace type testArray is varray(5) of number(3) PL/SQL存储过程里调用可变数组作为输出参数:create or replace function getTestArray return testArrayaso_data testArray:= testArray (); begin for v_count in 1.5 loop o_data.extend; o_data(v_count):= v_count; end loop;return o_data;end; 2.2.2 Java程序的编写 由存储过程返回的可变数组同样可以映射成java数组类型。但Java程序调用存储过程返回的可变数组方式和索引表方式却不相同,这一点应注意,具体方法如下:public static void main( ) ./调用存储过程. OracleCallableStatement stmt =(OracleCallableStatement)conn.prepareCall ( begin ? := getTestArray; end; ); stmt.registerOutParameter( 1, OracleTypes.ARRAY, testArray ); stmt.executeUpdate(); / 得到 ARRAY 对象 ARRAY simpleArray = stmt.getARRAY(1);/转换为java数组 String values = (String)simpleArray.getArray();/输出数组内容 for( int i = 0; i values.length; i+ ) System.out.println( row + i + = + valuesi + );2.3 嵌套表作为输出参数存 储过程中使用嵌套表,并不是直接将嵌套表作为输出参数,而是对嵌套表造型后以游标形式输出。嵌套表的基本功能与索引表相同,但嵌套表可以使用SQL进 行操作,其内容可通过SELECT 语句查询并造型后以游标形式返回。在大多数的查询统计中,常常需要返回结果集,这时使用嵌套表就尤其方便。笔者在开发过程中深刻体会到使用对象嵌套表 可以解决绝大多数的查询统计问题。下面着重介绍如何在存储过程里利用对象类型的嵌套表。对于任意的统计分析表格,我们可以将其简化成下面的输出形式: 统计项目1统计项目2统计项目3统计项目4名称1名称2这样我们把每一行看作是一个对象实例,该行的每一列则可以看作是该对象的一个属性,下面通过构造对象,然后对包含对象的嵌套表进行造型,返回游标得到结果集。2.3.1 存储过程的编写 首先构造统计对象如下: create or replace type TestObj as object( vname varchar2(20), -名称item1 number, -统计项目1item2 number, -统计项目2item3 number, -统计项目3item4 number -统计项目4);构造包含对象类型的嵌套表:create or replace type TestNestTable as table of TestObj;定义对索引表造型后的输出的游标类型:create or replace package out_param is type out_cur is ref cursor; 下面是嵌套表作为输出参数的存储过程:create or replace procedure testPro2(o_cur out out_param.out_cur ) is- 包含对象的嵌套表变量的声明v_objTable TestNestTable:= TestNestTable ();begin -嵌套表变量的使用v_objTabl.extend;v_objTable(1):= TestObj(张三,12,123,123,34);v_objTabl.extend;v_objTable(2):= TestObj(李四,22,2

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论