比如这样的数据类型定义:
CREATE OR REPLACE PACKAGE SmsService
IS
Type Message is Record(
error_code varchar2,
data varchar2,
message varchar2
);
Type msg_array is table of Message of Index By Binary_Integer;
PROCEDURE proc1(para1 out msg_array);
END;
Java里如何调用pl/sql存储过程返回record类型和集合类型(is table of record of Index By Binary_Integer)的结果呢?
不想用临时表(有一种情况可能是把数据放在临时表里,然后再用游标去访问临时表数据,最后返回一个游标,由java调用)
-----------------
用object,不用record.
object SQL支持,record属于PL/SQL。
给你一个TOM的例子:
1. create or replace type myScalarType
as object (x int,y varchar2(20),z date,
member function get_Y(x int) return varchar2);
2 .create or replace type myTableType as table of myScalarType;
3. create or replace function non_pipelined( p_like in varchar2 )
return myTableType
as
l_data myTableType;
begin
select myScalarType(user_id, username, created)
BULK COLLECT into l_data
from all_users
where username like p_like;
return l_data;
end;
4.select * from TABLE( non_pipelined( '%A%' ) );
-------------
不错,但是它也还是必须在数据库中创建2个type类型,不过总比创建临时表强.
经过我的整理,我可以把record记录集里的内容赋给你上面所说的myScalarType对象类型
假如环境是在scott/tiger用户下
1.create or replace type myScalarType
as object (deptno number,
dname varchar2(14));
2.create or replace type myTableType as table of myScalarType;
3.declare
Type RecType Is Record
(
deptno dept.deptno%type,
dname dept.dname%type
);
Type TabType Is Table Of RecType Index By Binary_Integer;
MyTab TabType;
vn number;
obj_type_tab MYTABLETYPE := MYTABLETYPE();
type cur is ref cursor;
dept_cur cur;
temp_deptno dept.deptno%type;
temp_dname dept.dname%type;
begin
vn:=1;
for varR in(select deptno,dname from dept order by deptno )
loop
MyTab(vn) := varR;
vn := vn + 1;
End Loop;
For varR In MyTab.First..MyTab.count
Loop
obj_type_tab.EXTEND;
obj_type_tab(obj_type_tab.LAST) := myscalartype(MyTab(varR).deptno, MyTab(varR).dname);
End Loop;
/*FOR rec IN (SELECT deptno, dname FROM TABLE(CAST(obj_type_tab AS MYTABLETYPE)))
LOOP
DBMS_OUTPUT.put_line('rec.deptno = ' || rec.deptno ||
'; rec.dname = ' || rec.dname);
END LOOP;*/
open dept_cur for SELECT deptno, dname FROM TABLE(CAST(obj_type_tab AS MYTABLETYPE));
loop
fetch dept_cur into temp_deptno,temp_dname;
exit when dept_cur%notfound;
DBMS_OUTPUT.put_line('rec.deptno = ' || temp_deptno ||
'; rec.dname = ' || temp_dname);
end loop;
close dept_cur;
end;
你可能会认为这是多此一举,其实我也有我的想法,就是说我们要讲究独立性,缺少依赖性,假如我有一个长事务,在这过程中可以有很多个中间表数据,如果每一个中间表数据都用一个临时表(如果在存储过程动态创建临时表,增加了SQL的复杂性),那也不行,有损数据库性能;如果每个中间表都用type类型替代,那就得*2个type类型了,也是很麻烦;所以有一个折中的办法,因为record类型不生成任何对象,也就是不占数据库空间,所以也不依赖于其它对象,独立性好,觉得用record代替中间表是可行的,但是最终产生的数据要返回并显示到应用程序页面上,而应用程序貌似不支持record,那我们就把record转换成object type类型,再以游标形式返回给应用程序就解决问题了
这只是我个人看法,不知道是否正确,如有问题大家也指出,或者能提出更好的解决方案
------------------------------------
--定义全局变量
create or replace package pkg_package as
type type_cursor is ref cursor;
type type_record is record(
test01 varchar2(32),
test02 varchar2(32),
test03 varchar2(32)
);
end;
/
--创建返回游标的存储过程
create or replace procedure p_temp_procedure(cur_out_arg out pkg_package.type_cursor)
is
begin
open cur_out_arg for select * from test;
end;
/
--调用
declare
cur_out_arg pkg_package.type_cursor;
rec_arg pkg_package.type_record;
begin
p_temp_procedure(cur_out_arg);
fetch cur_out_arg into rec_arg;
dbms_output.put_line(rec_arg.test01);
dbms_output.put_line(rec_arg.test02);
dbms_output.put_line(rec_arg.test03);
end;
/
----------------
create procedure p(my_cur out sys_refcursor)
as
begin
open my_cur for select * from emp;
end;
/