存储过程返回二维数组

Posted albert_think

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了存储过程返回二维数组相关的知识,希望对你有一定的参考价值。

 存储过程越来越多的应用到项目当中了,不罗嗦了先来看看JAVA怎么从oracle接收对象数组。 

Sql代码  技术分享图片
  1.    
  2. --建立oracle对象   
  3. CREATE OR REPLACE TYPE PERSON AS OBJECT (   
  4. --如果你执意使用VARCHAR2有一定几率出现乱码和ASCII码(貌似和驱动有关)   
  5. --为了避免平台,服务器中间件,驱动等等因素而造成的   
  6. --可能出现乱码(无法识别)和以0X开头的16进制ASCII等情况请使用NVARCHAR2   
  7.   P_ID NVARCHAR2(32),   
  8.   P_NAME NVARCHAR2(16),   
  9.   P_AGE NVARCHAR2(24),   
  10.   P_PROJECT NVARCHAR2(32) )   
  11. --建立对象数组   
  12. CREATE OR REPLACE TYPE PERSON_TABLE_TYPE IS TABLE OF PERSON   
  13. --建立测试用存储过程   
  14. --PS:这个过程是在我的一个包(TEST.DEMO)里面的,如果单独写成过程请create or replace   
  15. PROCEDURE GETBEAN_OBJTABLE(V_TABLE OUT PERSON_TABLE_TYPE)   
  16.   AS   
  17.   BEGIN V_TABLE := PERSON_TABLE_TYPE();   
  18.     FOR I IN 1 .. 5 LOOP   
  19.     V_TABLE.EXTEND; V_TABLE(I) := PERSON(‘23231123232‘||I,   
  20.                                              ‘第‘||I||‘代‘,   
  21.                                                   ‘20‘||I,   
  22.                                            ‘2010-1-1‘||I);   
  23.   END LOOP;   
  24. END;   


JAVA端 

Java代码  技术分享图片
  1. //如果你使用JDBC,  
  2. //你可以强转conn为oracleConnection也可以像我一样强转CallableStatement为OracleCallableStatement。  
  3. //但如果你使用诸如tomcat的DBCP等连接池请首先转换为native连接,然后转换为oracle连接,直接强转是无效的!  
  4. //(最后释放关闭的连接是连接池的连接而不是oracle的连接)   
  5. conn = DbHelperImpJdbc.getInstance().getConn();  
  6. cs = (OracleCallableStatement) conn.prepareCall("{call PKG_DEMO.GETBEAN_OBJTABLE(?)}");  
  7. cs.registerOutParameter(1, OracleTypes.ARRAY, "PERSON_TABLE_TYPE".toUpperCase());  
  8. ARRAY obj = (ARRAY) cs.getArray(1);  
  9. Datum[] datas = obj.getOracleArray();//获取对象  
  10. //遍历对象数组  
  11. for(int i=0;i<datas.length;i++){  
  12.     System.out.println("对象"+i);  
  13.     //获取属性  
  14.     Object[] beanAttributes = ((STRUCT) datas[i]).getOracleAttributes();  
  15.     //遍历属性  
  16.     for(int m=0;m<beanAttributes.length;m++){  
  17.         System.out.println("  "+beanAttributes[m]);  
  18.     }  
  19. }  


打印结果: 
对象0 
  232311232321 
  第1代 
  201 
  2010-1-11 
对象1 
  232311232322 
  第2代 
  202 
  2010-1-12 
对象2 
  232311232323 
  第3代 
  203 
  2010-1-13 
对象3 
  232311232324 
  第4代 
  204 
  2010-1-14 
对象4 
  232311232325 
  第5代 
  205 
  2010-1-15 

接下来我们来看看怎么从过程中接收二维数组,由于二维数组的接收网上资料很少,通过自己的研究发现二维数组可以先转换成一维数组,然后每个元素再逆向转换成Oracle.ARRAY,再然后按照一维数组如法炮制。 

Sql代码  技术分享图片
  1. --建立一维数组  
  2. --PS也请使用NVARCHAR2  
  3. CREATE OR REPLACE TYPE TYPE_VARCHAR IS TABLE OF NVARCHAR2(2000)  
  4. --建立二维数组  
  5. CREATE OR REPLACE TYPE TYPE_VARCHAR_TABLE IS TABLE OF TYPE_VARCHAR  
  6. --建立测试用过程  
  7.      PROCEDURE GETBEAN_ARRAYTABLE(V_TABLE OUT TYPE_VARCHAR_TABLE)  
  8.        AS  
  9.        BEGIN  
  10.          V_TABLE:=TYPE_VARCHAR_TABLE();  
  11.          FOR I IN 1 .. 5 LOOP  
  12.            V_TABLE.EXTEND;  
  13.            V_TABLE(I):=NEW TYPE_VARCHAR(‘23231123232‘||I,  
  14.                                         ‘ 第‘||I||‘代‘,  
  15.                                         ‘20‘||I,  
  16.                                         ‘2010-1-1‘||I);  
  17.          END LOOP;  
  18.        END;  


JAVA端 

Java代码  技术分享图片
  1. conn = DbHelperImpJdbc.getInstance().getConn();  
  2. cs = (OracleCallableStatement) conn.prepareCall("{call PKG_DEMO.GETBEAN_ARRAYTABLE(?)}");  
  3. cs.registerOutParameter(1, OracleTypes.ARRAY, "TYPE_VARCHAR_TABLE".toUpperCase());  
  4. cs.execute();  
  5. ARRAY obj = (ARRAY) cs.getArray(1);  
  6. //获取第一维度  
  7. Object[] firstDimension=(Object[]) obj.getArray();  
  8. for(int i=0;i<firstDimension.length;i++){  
  9.     System.out.println("对象"+i);  
  10.     //将第一维度元素转成ARRAY之后获取数组再将该数组元素转换成数组,  
  11.     //这便是第二维度数组  
  12.     Object[] secondDimension=(Object[]) ((ARRAY)firstDimension[i]).getArray();  
  13.     for(int m=0;m<secondDimension.length;m++){  
  14.         System.out.println("  "+secondDimension[m]);  
  15.     }  
  16. }  


打印结果同上。 

总结:使用二维数组比对象数组灵活的多,如果我们要为返回结果集中删减字段,就必须要先去更改oracle的对象,这样很不灵活。而二维数组的可伸缩性就非常好了。 


































以上是关于存储过程返回二维数组的主要内容,如果未能解决你的问题,请参考以下文章

无法从 JDBC 获取 OUT 参数中的二维关联数组

如何给SQLSERVER存储过程传递数组参数

存储过程返回一个数组;如何在 SQL 中使用?

输入对象数组作为输入并返回一个数组作为存储过程的输出

返回二维数组子数组联通和最大

存储过程与数组连接查询