您的位置:首页 > 数据库 > Oracle

java oracle传入和取得自定义数组(二维数组)

2015-12-08 16:16 465 查看

环境

oracle数据库为11g

oracle数据库准备

--创建测试表
drop table t_parent;
drop table t_child;
create table t_parent(
id number(10),
name varchar2(100),
title varchar2(100)
);

create table t_child(
id number(10),
parent_id number(10),
child_name varchar2(100),
child_title varchar2(100)
);
--创建测试序列
create sequence seq_test
minvalue 1
maxvalue 9999999999
start with 1
increment by 1
nocache;
--创建oracle数组类型
drop type t_child_lst_map;
drop type t_child_lst;
drop type t_parent_lst;

create or replace type t_parent_ as object (
name varchar2(100),
title varchar2(100)
);
create or replace type t_child_ as object (
child_name varchar2(100),
child_title varchar2(100)
);
create or replace type t_parent_lst as table of t_parent_;
create or replace type t_child_lst as table of t_child_;
create or replace type t_child_lst_map as table of t_child_lst;

--存储过程
--包头
create or replace package p_arraylist_test is
--输入输出自定义数组参数的存储过程
procedure proc_lst_test(i_parent_lst    in t_parent_lst, --parent列表
i_child_map_lst in t_child_lst_map, --child列表集合,一个map元素对应一个child_lst,其下标与 parent列表的下标相同。
o_oarent_list   out t_parent_lst, --parent列表
o_ret           out number);
end p_arraylist_test;
--包体
create or replace package body p_arraylist_test is

--输入输出自定义数组参数的存储过程
procedure proc_lst_test(i_parent_lst    in t_parent_lst, --parent列表
i_child_map_lst in t_child_lst_map, --child列表集合,一个map元素对应一个child_lst,其下标与 parent列表的下标相同。
o_oarent_list   out t_parent_lst, --parent列表
o_ret           out number) as
var_parent    t_parent_;
var_child_lst t_child_lst;
var_child     t_child_;
var_parent_id number;
begin
for i in 1 .. i_parent_lst.count loop
--取得parent各列的值
var_parent := i_parent_lst(i);

--插入parent表
insert into t_parent
(id, name, title)
values
(seq_test.nextval, var_parent.name, var_parent.title) return id into var_parent_id;

--取得该parent对应的child列表
var_child_lst := i_child_map_lst(i);

for j in 1 .. var_child_lst.count loop
var_child := var_child_lst(j);

--插入child表
insert into t_child
(id, parent_id, child_name, child_title)
values
(seq_test.nextval,
var_parent_id,
var_child.child_name,
var_child.child_title);
end loop;

end loop;
-- 给数组赋值
o_oarent_list := t_parent_lst();
for idx in (select * from t_parent where rownum < 5) loop
o_oarent_list.extend; -- 扩展数组,以便于给数组赋值
-- 赋值的时候,下标必须从 1 开始,否则会出现 “ 下标超出数量 ” 的错误
o_oarent_list(o_oarent_list.count) := t_parent_(idx.name, idx.title);
end loop;

o_ret := 1;

exception
when others then
begin
o_ret := 0;
raise;
end;
end proc_lst_test;

end p_arraylist_test;

--常见问题:
/*
1.存入的值为空,但是记录有插入,插入值为空
解决:查看当前lib包中有没有包含orai18n.jar库.
*/

--清除痕迹
drop table t_parent;
drop table t_child;

drop type t_child_lst_map;
drop type t_child_lst;
drop type t_parent_lst;
drop type t_parent_;
drop type t_child_;

drop sequence seq_test;
drop package p_arraylist_test;


java代码

package com.lytz.work;

import java.sql.Connection;
import java.sql.DriverManager;

/**
* TestCon.java 说明
*
* @author zhengzy
* @date 2015年12月8日下午3:31:57
*/
public class TestCon {
public static Connection getConn() {
String URL = "jdbc:oracle:thin:@192.168.15.45:1521:lytzats";
String user = "atsol";// 这里替换成你自已的数据库用户名
String password = "atsol";// 这里替换成你自已的数据库用户密码
Connection connection = null;
try {
Class.forName("oracle.jdbc.driver.OracleDriver");
System.out.println("类实例化成功!");
connection = DriverManager.getConnection(URL, user, password);
System.out.println("创建连接对像成功!");
} catch (Exception err) {
err.printStackTrace();
return null;
}
return connection;
}

public static void main(String[] args) {
getConn();
}
}


package com.lytz.work;

import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.ArrayList;

import oracle.jdbc.OracleTypes;
import oracle.sql.ARRAY;
import oracle.sql.ArrayDescriptor;
import oracle.sql.Datum;
import oracle.sql.STRUCT;
import oracle.sql.StructDescriptor;

import com.lytz.db.manager.DBUtil;

/**
* Test.java 说明
*
* @author zhengzy
* @date 2015年12月4日下午2:20:28
*/
public class Test {

public static void main(String[] args) throws InterruptedException, SQLException {

Connection con = null;
CallableStatement  cstmt = null;

//      con = DBUtil.getInstance().getConnection();
con = TestCon.getConn();

ArrayList<Parent> plst = new ArrayList<Parent>();
for (int i = 0; i < 10; i++) {
Parent p = new Parent();
p.setName("name" + i);
p.setTitle("title" + i);
plst.add(p);
}

ArrayList<ArrayList<Child>> clstMap = new ArrayList<ArrayList<Child>>();
for (int i = 0; i < 10; i++) {
ArrayList<Child> clst = new ArrayList<Child>();
for (int j = 0; j < 10; j++) {
Child c = new Child();
c.setChild_name("childName" + j);
c.setChild_title("childT" + j);
clst.add(c);
}
clstMap.add(clst);
}

//此处的参数必须为大写
ArrayDescriptor parentLstDesc = ArrayDescriptor.createDescriptor("T_PARENT_LST", con);
StructDescriptor parentDesc = StructDescriptor.createDescriptor("T_PARENT_", con);
ArrayDescriptor childLstMapDesc = ArrayDescriptor.createDescriptor("T_CHILD_LST_MAP", con);
ArrayDescriptor childLstDesc = ArrayDescriptor.createDescriptor("T_CHILD_LST", con);
StructDescriptor childDesc = StructDescriptor.createDescriptor("T_CHILD_", con);

ArrayList<STRUCT> pstruct = new ArrayList<STRUCT>();
// 转换plst为Oracle 对象数组
for (int i = 0; i < plst.size(); i++) {
Parent p = plst.get(i);
Object[] record = new Object[2];
record[0] = p.getName();
record[1] = p.getTitle();
STRUCT item = new STRUCT(parentDesc, con, record);
pstruct.add(item);
}
ARRAY dataps = new ARRAY(parentLstDesc, con, pstruct.toArray());

ArrayList<ARRAY> cMap = new ArrayList<ARRAY>();
// 转换clst为Oracle 对象数组
for (int i = 0; i < clstMap.size(); i++) {
ArrayList<Child> childLst = clstMap.get(i);
ArrayList<STRUCT> cstruct = new ArrayList<STRUCT>();
for (int j = 0; j < childLst.size(); j++) {
Child c = childLst.get(j);
Object[] record = new Object[2];
record[0] = c.getChild_name();
record[1] = c.getChild_title();
STRUCT item = new STRUCT(childDesc, con, record);
cstruct.add(item);
}
ARRAY datacs = new ARRAY(childLstDesc, con, cstruct.toArray());
cMap.add(datacs);
}
ARRAY datacsMap = new ARRAY(childLstMapDesc, con, cMap.toArray());

try {
cstmt = con.prepareCall("{call P_ARRAYLIST_TEST.PROC_LST_TEST(?,?,?,?)}");

cstmt.setArray(1, dataps);
cstmt.setArray(2, datacsMap);
cstmt.registerOutParameter(3, OracleTypes.ARRAY, "T_PARENT_LST");
cstmt.registerOutParameter(4, OracleTypes.INTEGER);
cstmt.execute();

int error_code = cstmt.getInt(4);
System.out.println(error_code);

ARRAY ary = (ARRAY) cstmt.getArray(3);
Datum[] dtm = ary.getOracleArray();
for (int i = 0; i < dtm.length; i++) {
STRUCT st = (STRUCT) dtm[i];
Object obj[] = st.getAttributes();
System.out.println(obj[0] + "---" + obj[1]);
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
if (cstmt != null) {
cstmt.close();
cstmt = null;
}
if (con != null) {
con.close();
con = null;
}
} catch (SQLException ex) {
logger.error("数据库资源释放出错:" + ex.getMessage());
// ex.printStackTrace();
}
}
}
}


结果



问题

问题:

java.sql.SQLException: ORA-06530: 引用未初始化的组合

原因:

数组初始化方式有问题

procedure proc_lst_test_out2(o_oarent_ out t_parent_ --parent列表
) as
begin

--o_oarent_ := t_parent_('test', 'title');
o_oarent_.name := 'test';
o_oarent_.title := 'title';

end proc_lst_test_out2;


以上代码是不行的

解决:

procedure proc_lst_test_out2(o_oarent_ out t_parent_ --parent列表
) as
begin

o_oarent_ := t_parent_('test', 'title');

end proc_lst_test_out2;


参考

Java中传入和取得oracle10g存储过程返回的数组对象(多维数组)http://blog.csdn.net/hunterdiary/article/details/6063279
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息