现在的位置: 首页 > 综合 > 正文

java oracle存储过程/函数(2):字符串数组传出存储过程,动态sql如何fetch到游标

2013年04月27日 ⁄ 综合 ⁄ 共 7911字 ⁄ 字号 评论关闭

    在(1)中,我们讲了如何传入String数组和int数组。这里,讲下如何传出String数组。可能看了代码之后,有的朋友会有疑问:为什么要传出String数组?直接传出一个游标不好吗?

    这里简单说下初衷:游标基本上只能从table中传出,或者,从自定义数组中select出来作为一个游标。我这里举的例子是查询表中的某一列的值,但实际应用中,可能需要转化,例如:A-》可用,N-》不可用,U-》未知。。。等等一切其他可能需要把结果做一个过滤的情况,number数值同样如此。因此,个人觉得,就String作为数组传出也是必要的。但愿,这里的猜测只是多疑。

    另外,本篇的存储过程中还涉及了如何利用游标执行在存储过程中组织的动态sql的相关信息,敬请注意。

    好了,习惯了在开篇罗嗦几句,大家忍受下。如果找不到java类,请在该系列前面的文章中找。

 

接着上代码:

 

2varchar2、number数组传出.sql

 

drop table T_VarcharArray;
create table T_VarcharArray(
    id number(10),
    name varchar2(100)
    );

insert into T_VarcharArray values(1,'你好');
insert into T_VarcharArray values(2,'呵呵你好啊');
insert into T_VarcharArray values(2,'你好啊');
insert into T_VarcharArray values(2,'你好啊,祝你顺利!');
insert into T_VarcharArray values(3,'你好吗');
insert into T_VarcharArray values(4,'朋友你好');
insert into T_VarcharArray values(5,'呵呵你好吗朋友');
insert into T_VarcharArray values(6,'你好');
insert into T_VarcharArray values(7,'你好');
insert into T_VarcharArray values(8,'你好');
commit;

drop type T_VARCHAR;

--创建一个与T_VarcharArray的name同类型的不定长数组的定义
create or replace type T_VARCHAR as table of varchar2(100);
/

drop type T_NUMBER;

--创建一个与T_VarcharArray的id同类型的不定长数组的定义
create or replace type T_NUMBER as table of number(10);
/

create or replace procedure P_VARCHAR2_LST_STATIC(
    i_name varchar2, --输入参数,要查询的name与之相等
    o_t_varchar OUT t_varchar, --输出参数,为定义的不定长varchar2数组
    o_n_ret OUT number --输出参数,正常结束,则输出0,否则抛出异常
    )
is
v_cur sys_refcursor; --定义一个游标变量
v_name T_VarcharArray.name%TYPE; --定义一个与T_VarcharArray表的name字段一样的类型的变量
begin
    --首先初始化一个空的字符串数组对象,此时o_t_varchar.COUNT=0;
    o_t_varchar := t_varchar(); --注意 := 是PL/SEL中的赋值,而=表示相等。
    --打开游标
    open v_cur for select name from T_VarcharArray where name = i_name;
    loop
        --把只有一个字段name的游标fetch到变量。
        --如果是整个table的所有列,可以用%ROWTYPE来定义v_rec,接下来的系列中可能会用到,请注意。
        fetch v_cur into v_name;
        exit when v_cur%NOTFOUND; --这句紧接fetch,表示如果游标中没有值了,则退出该循环。
        o_t_varchar.EXTEND; --数组扩展长度,第一次loop时,COUNT=1,以后依次+1;
        o_t_varchar(o_t_varchar.COUNT):=v_name; --把v_name赋值给输出数组的最后一个元素。
    end loop;

    --千万千万记得打开了的游标要关闭。除非你返回一个游标作为存储过程的输出参数或函数的输出值
    close v_cur;
   
    o_n_ret :=0;
    exception when others then
    raise;
end;
/

create or replace procedure P_VARCHAR2_LST_DYMANTIC(
    i_name varchar2, --输入参数,要查询的name中包含的字符串
    o_t_varchar OUT t_varchar, --输出参数,为定义的不定长varchar2数组
    o_n_ret OUT number --输出参数,正常结束,则输出0,否则抛出异常
    )
is
v_cur sys_refcursor; --定义一个游标变量
v_name T_VarcharArray.name%TYPE; --定义一个与T_VarcharArray表的name字段一样的类型的变量
v_sql varchar2(1000); --定义需要动态执行的sql语句
begin
    --组织动态sql
    --注意,在oracle的字符串常量中,两个''表示一个',即在'前再加一个'表示转义,与java中需要/来转义一样。
    --单个的'需要如此,其他的特殊字符未做研究。另外,||表示连接两个常量字符串。
    v_sql := 'select name from T_VarcharArray where name like ''%'||i_name||'%''';

    --首先初始化一个空的字符串数组对象,此时o_t_varchar.COUNT=0;
    o_t_varchar :=t_varchar();
    --打开游标
    open v_cur for v_sql;
    loop
        --把只有一个字段name的游标fetch到变量。
        --如果是整个table的所有列,可以用%ROWTYPE来定义v_rec,接下来的系列中可能会用到,请注意。
        fetch v_cur into v_name;
        exit when v_cur%NOTFOUND; --这句紧接fetch,表示如果游标中没有值了,则退出该循环。
        o_t_varchar.EXTEND; --数组扩展长度,第一次loop时,COUNT=1,以后依次+1;
        o_t_varchar(o_t_varchar.COUNT):=v_name; --把v_name赋值给输出数组的最后一个元素。
    end loop;

    --千万千万记得打开了的游标要关闭。除非你返回一个游标作为存储过程的输出参数或函数的输出值
    close v_cur;
   
    o_n_ret :=0;
    exception when others then
    raise;
end;
/

create or replace procedure P_NUMBER_LST_STATIC(
    i_id number, --输入参数,要查询的name与之相等
    o_t_number OUT t_number, --输出参数,为定义的不定长number数组
    o_n_ret OUT number --输出参数,正常结束,则输出0,否则抛出异常
    )
is
v_cur sys_refcursor; --定义一个游标变量
v_id T_VarcharArray.id%TYPE; --定义一个与T_VarcharArray表的id字段一样的类型的变量
begin
    --首先初始化一个空的字符串数组对象,此时o_t_varchar.COUNT=0;
    o_t_number := t_number(); --注意 := 是PL/SEL中的赋值,而=表示相等。
    --打开游标
    open v_cur for select id from T_VarcharArray where id = i_id;
    loop
        --把只有一个字段id的游标fetch到变量。
        --如果是整个table的所有列,可以用%ROWTYPE来定义v_rec,接下来的系列中可能会用到,请注意。
        fetch v_cur into v_id;
        exit when v_cur%NOTFOUND; --这句紧接fetch,表示如果游标中没有值了,则退出该循环。
        o_t_number.EXTEND; --数组扩展长度,第一次loop时,COUNT=1,以后依次+1;
        o_t_number(o_t_number.COUNT):=v_id; --把v_name赋值给输出数组的最后一个元素。
    end loop;

    --千万千万记得打开了的游标要关闭。除非你返回一个游标作为存储过程的输出参数或函数的输出值
    close v_cur;
   
    o_n_ret :=0;
    exception when others then
    raise;
end;
/

Varchar2NumberArrayOut.java

 

抱歉!评论已关闭.