帮看一个jdbc获取oracle存储过程自定义类型的有关问题
来源:互联网 发布:淘宝评论设置方法 编辑:程序博客网 时间:2024/06/05 01:14
SQL code
--初始化数据create table student( id int, name varchar(20), age int, sex varchar(2), birth date);insert into student values(1,'张三',23,'男',sysdate);insert into student values(2,'李四',24,'男',sysdate);insert into student values(3,'王五',25,'男',sysdate);--创建包create or replace package TestPackage as type TestRecord1 is record(id int,name varchar(20)); type TestTable1 is table of TestRecord1 index by binary_integer; procedure TestProcedure1(result out TestTable1);end TestPackage;--建存储过程create or replace package body TestPackage as procedure TestProcedure1(result out TestTable1) as record1 TestRecord1; v_id int; v_name varchar(20); cursor1 sys_refcursor; begin open cursor1 for select id,name from student; loop fetch cursor1 into v_id,v_name; if cursor1%notfound then exit; else record1.id := v_id; record1.name := v_name; result(result.count) := record1; end if; end loop; end TestProcedure1;end TestPackage;--调用存储过程正确declare table1 TestPackage.TestTable1; i int := 0;begin TestPackage.TestProcedure1(table1); while i < table1.count loop dbms_output.put_line(table1(i).id); i := i + 1; end loop;end;
Java code
//这个就有错了Class.forName("oracle.jdbc.driver.OracleDriver");Connection con = DriverManager.getConnection("jdbc:oracle:thin:@127.0.0.1:1521:test","xxx","yyy");OracleCallableStatement cs = (OracleCallableStatement) con.prepareCall("{call TestPackage.TestProcedure1(?)}");cs.registerOutParameter(1, oracle.jdbc.OracleTypes.ARRAY,"TestPackage.testTable1".toUpperCase());cs.execute();ARRAY array = cs.getARRAY(1);Datum[] data = array.getOracleArray();for(Datum d:data){ STRUCT struct = (STRUCT)d; Datum[] stringValue = struct.getOracleAttributes(); Object[] noStringValue = struct.getAttributes(); System.out.print((BigDecimal)noStringValue[0]);//id System.out.println(new String(stringValue[1].getBytes()));//name}cs.close();con.close();
------解决方案--------------------------------------------------------
- Java code
//java调用oracle存储过程时数组参数import oracle.sql.STRUCT;import oracle.sql.StructDescriptor; public ReturnType BatchAddTerminals(TerminalUsersType[] tus) { ReturnType ret = new ReturnType(); ret.setCode(0); //Connection conn = C3P0Pool.getInstance().getConn(); GeneralConnect gc = new GeneralConnect(); Connection conn = gc.getConnection(); oracle.jdbc.OracleConnection oracleConn = (oracle.jdbc.OracleConnection) conn; CallableStatement stat = null; if (oracleConn != null) { try { StructDescriptor sd = new StructDescriptor( "TYPE_TERMINAL_USER", oracleConn); STRUCT[] results = new STRUCT[tus.length]; for (int i = 0; i < tus.length; i++) { Object[] o = new Object[7]; o[0] = new Integer(tus[i].getEpid()); o[1] = new String(tus[i].getUserName()); o[2] = new String(tus[i].getMobile()); o[3] = new String(tus[i].getTermCode()); o[4] = new String(tus[i].getUserDesc()); o[5] = new String(tus[i].getSmsMobile()); o[6] = new String(tus[i].getPassword()); results[i] = new STRUCT(sd, oracleConn, o); } String sql = "{call PACK_USER_TERMINALS.BatchAddTerminals(?,?,?)}"; stat = oracleConn.prepareCall(sql); stat.registerOutParameter(2, java.sql.Types.INTEGER); stat.registerOutParameter(3, java.sql.Types.VARCHAR); oracle.sql.ArrayDescriptor des_TABLE_TERMINAL_USER = oracle.sql.ArrayDescriptor .createDescriptor("TABLE_TERMINAL_USER", oracleConn); oracle.sql.ARRAY ora_array1 = new oracle.sql.ARRAY( des_TABLE_TERMINAL_USER, oracleConn, results); stat.setArray(1, ora_array1); stat.execute(); ret.setCode(stat.getInt(2)); ret.setDesc(stat.getString(3)); } catch (java.sql.SQLException ex) { Log.getInstance().outLog("访问数据库异常" + ex.getMessage()); ret.setDesc("访问数据库异常" + ex.getMessage()); } catch (Exception ex) { Log.getInstance().outLog("其他异常" + ex.getMessage()); ret.setDesc("其他异常" + ex.getMessage()); } finally { CloseDB.attemptClose(stat); CloseDB.attemptClose(conn); } } return ret; }
ArrayDescriptor.createDescriptor(type, conn);schema级别对象类型是可以的只是单独的名字,默认前面是schema,但是不能加package,应该是oracle jdbc里面代码的问题解决的办法只有对package.type建立一个同义词了(尝试下同义词)要么你就用schema级别的对象(自定义类型放在包外定义),jdbc这点不是很好这是一个长久以来的缺陷To my knowledge, the Oracle JDBC driver does not support using the ArrayDescriptor for array data types (varray or nested table) that are defined inside of a package. The same is true for StructDescriptor as well. If you want to use array and object data types, you must define them outside of a package. Then you'll be able to use the descriptors in your JDBC programs.As far as I know, you can only create an "ArrayDescriptor" and a "StructDescriptor" for database types.In other words, types that were created using the CREATE TYPE (DDL) statement.You cannot create an "ArrayDescriptor" or a "StructDescriptor" for types created in PL/SQL packages.
- 帮看一个jdbc获取oracle存储过程自定义类型的有关问题
- Oracle复合类型参数的存储过程以及JDBC调用
- jdbc中调用oracle 返回游标类型的存储过程
- jdbc中调用oracle 返回游标类型的存储过程
- Oracle复合类型参数的存储过程以及JDBC调用
- 详细讲解有关Oracle存储过程的相关问题
- 详细讲解有关Oracle存储过程的相关问题
- 有关oracle存储过程的6个问题
- java调用oracle存储过程的自定义类型(可变数组)。
- DAO调用Oracle带自定义类型的存储过程.
- java调用oracle存储过程的自定义类型(可变数组)。
- Java获取Oracle存储过程返回的自定义嵌套表
- 有关于存储过程的一个笑话
- Oracle存储过程中使用记录类型注意的问题
- Oracle存储过程-使用记录类型注意的问题[%type]
- Oracle 存储过程中调用自定义的函数问题?
- 通过JDBC创建Oracle的存储过程
- 有关存储过程的like问题
- mfc 托盘技术(taskbar status area)
- 讲解ORACLE JOB INTERVAL参数设置
- 为ExpandableListView中每个childView绑定不同视图
- nasm: error: more than one input file specified 原因
- GML简介-例子
- 帮看一个jdbc获取oracle存储过程自定义类型的有关问题
- 并行编程与PLINQ-任务并行
- 华为和思科IPV6初探,IPV6中的link-local address
- 冒泡排序
- 巧用SendMessage函数扩展Treeview功能
- Android AlarmManager 使用指南
- xp和win 2003远程桌面强制进入命令_远程登录t人命令
- OSI七层模型与TCP/IP五层模型(网摘)
- Android中的TextView 、EditText、Activity、Intent实例小计算器