• Java调用存储过程返回数组


    Java调用存储过程:

    结合SQL操作与存储过程

    create procedure set_death_age(poet VARCHAR2, poet_age NUMBER)

    poet_id NUMBER;

    begin SELECT id INTO poet_id FROM poets WHERE name = poet;

    INSERT INTO deaths (mort_id, age) VALUES (poet_id, poet_age);

    end set_death_age;  

    下面是调用上面存储过程的Java代码:

    public static void setDeathAge(Poet dyingBard, int age) throws SQLException{

    Connection con = null;

    CallableStatement proc = null;

    try {

    con = connectionPool.getConnection();

    proc = con.prepareCall("{ call set_death_age(?, ?) }");

    proc.setString(1, dyingBard.getName());

    proc.setInt(2, age);

    proc.execute();

    }

    finally {

    try { proc.close(); }

    catch (SQLException e) {}

    con.close();

    }

    }  

    Functions

    存储过程可以有返回值,所以CallableStatement类有类似getResultSet这样的方法来获取返回值。当存储过程返回一个值时,你必须使用registerOutParameter方法告诉JDBC驱动器该值的SQL类型是什么。你也必须调整存储过程调用来指示该过程返回一个值。

    下面接着上面的例子。这次我们查询Dylan Thomas逝世时的年龄。这次的存储过程使用:

    create function snuffed_it_when (VARCHAR) returns integer ''declare

    poet_id NUMBER;

    poet_age NUMBER;

    begin

    --first get the id associated with the poet.

    SELECT id INTO poet_id FROM poets WHERE name = $1;

    --get and return the age.

    SELECT age INTO poet_age FROM deaths WHERE mort_id = poet_id; 

    return age;

    end;

    下面是调用这个存储过程的Java代码:

    connection.setAutoCommit(false);

    CallableStatement proc = connection.prepareCall("{ ? = call snuffed_it_when(?) }"); proc.registerOutParameter(1, Types.INTEGER);

    proc.setString(2, poetName); cs.execute();

    int age = proc.getInt(2); 

    在使用存储过程中,我们有时需要传递可变数组,存在两种情况,存储过程有输入或输出参数为自定义可变数组的。在java代码中,如何正确调用oracle存储过程的自定义可变数组类型,在这里做一下示例说明.

    java调用oracle存储过程的自定义类型:

    plsql定义字符串和数值型可变数组:

    一.定义全局类型:

    CREATE OR REPLACE TYPE USERSEQID_ARRAY IS VARRAY(50000) OF NUMBER(9)

    CREATE OR REPLACE TYPE USERNAME_ARRAY  AS VARRAY(32) of varchar(32)

    CREATE OR REPLACE TYPE USERPWD_ARRAY  AS VARRAY(50000) of varchar(60)

    二.java调用输出参数为自定义数组的存储过程:

    2.1 输出参数为自定义数组的存储过程make_logincard_pro:

    procedure make_logincard_pro (

    p_cardsuitcode in varchar,

    p_userseqidArr out USERSEQID_ARRAY ,

    p_usernameArr out USERNAME_ARRAY

    )

    IS

    v_addedtime date:= sysdate;

    BEGIN

        FOR ii IN 1 .. 10 LOOP

            IF p_userseqidArr IS NULL THEN

              p_userseqidArr := USERSEQID_ARRAY(ii);

            ELSE

               p_userseqidArr.EXTEND;   --超过数组定义大小(50000)将抛出异常 

               p_userseqidArr(ii) := ii;               

            END IF;

            IF p_usernameArr IS NULL THEN

              p_usernameArr := USERSEQID_ARRAY(ii || 'TT');

            ELSE

               p_usernameArr.EXTEND;      --超过数组定义大小(32)将抛出异常

               p_usernameArr(ii) := ii || 'TT';                

            END IF;

        END LOOP

    END make_logincard_pro ;

     2.2JAVA调用存储过程make_logincard_pro:

    //代码片段

    Connection con = session.connection();

    java.sql.CallableStatement cst = con

            prepareCall("call CNBT.test_pro(?,?,?)");

    cst.setString(1, cardSuitCode);

    cst.registerOutParameter(2, OracleTypes.ARRAY,"USERSEQID_ARRAY");

    cst.registerOutParameter(3, OracleTypes.ARRAY,"USERNAME_ARRAY");

    java.sql.Array userSeqIdArr = cst.getArray(2);

    java.sql.Array userNameArr = cst.getArray(3);

    if ( userSeqIdArr  != null ) ...{

        BigDecimal userSeqIdList[] = (BigDecimal[])userSeqIdArr.getArray();//数据库的number映射为BigDecimal

        //。。。。。。

    }

    if ( userNameArr  != null ) ...{

        String userNameList[] = (String[])userNameArr.getArray();

        //。。。。。。

    }

    --------------------------------------------------------------------------------

    三. java调用输入参数为自定义数组的存储过程:

    3.1 输入参数为自定义数组的存储过程update_logincard_pwd:

      /**//**********************************************

       *          update_logincard_pwd               *

       *功能描述:更新密码存储过程         *

       *输入参数:                                         *

       *输出参数:                                         *

       *作者:hanjiong                                    *

       ***********************************************/  

    procedure update_logincard_pwd (

         p_userSeqIdList in USERSEQID_ARRAY,

         p_userPwdList in USERPWD_ARRAY,

         p_resultcode out number

       );

    3.2 java调用存储过程update_logincard_pwd:

    //代码片段

    ..........................

    Connection con = session.connection();//使用的weblogic数据源

    oracle.jdbc.OracleCallableStatement cst2 = (oracle.jdbc.OracleCallableStatement)con

                                        .prepareCall(

                                        "call CNBT.update_logincard_pwd(?,?,?)");

                                weblogic.jdbc.wrapper.Connection weblogicConn = (weblogic.jdbc.wrapper.Connection)con;

                                oracle.jdbc.OracleConnection oracleConn = (oracle.jdbc.OracleConnection)weblogicConn.getVendorConnection();//转化connection

                                oracle.sql.ArrayDescriptor des_USERSEQID_ARRAY =

                                        oracle.sql.ArrayDescriptor.createDescriptor("USERSEQID_ARRAY",oracleConn);

                                oracle.sql.ArrayDescriptor des_USERPWD_ARRAY =

                                        oracle.sql.ArrayDescriptor.createDescriptor("USERPWD_ARRAY",oracleConn);

                                oracle.sql.ARRAY ora_array1 = new oracle.sql.ARRAY(des_USERSEQID_ARRAY, oracleConn, userAccSeqIdArr);

                                oracle.sql.ARRAY ora_array2 = new oracle.sql.ARRAY(des_USERPWD_ARRAY, oracleConn, userPwdList);

                                cst2.setArray(1, ora_array1);

                                cst2.setArray(2, ora_array2);

                                cst2.registerOutParameter(3, java.sql.Types.INTEGER);

                                cst2.execute();

                                updateCode = cst2.getInt(3);

    .....................................

    ....................................

    因为我使用的是weblogic配置的数据源,在取得的connection对象时需要注意,通过数据源取得的Connection对象为weblogic.jdbc.wrapper.Connection,所以不能直接转化为oracle.jdbc.OracleConnection,否则会出现java.lang.ClassCastException异常,所以我们要通过weblogic.jdbc.wrapper.Connection.getVendorConnection()取得java.sql.Connection,在强制转化为oracle.jdbc.OracleConnection。

    --------------------------------------------------------------------------------

    通过上述两种情况,就可以在Oracle存储过程中使用zid

  • 相关阅读:
    Cannot retrieve repository metadata (repomd.xml) for repository: fedora. P、、、
    Fedora 学习总结
    Gnome 高级配置
    [置顶]Fedora 13,14,15安装LAMP
    如何删去Fedora下应用程序菜单中的多余程序启动器?
    运用Telnet在windowsxp中与虚拟机中fedora14互联
    运用Telnet在Windows xp中与虚拟机中fedora14互连
    netstat 的应用
    在 fedora14 下升级 firefox 到 firefox4 的两种方案
    windows 中相关CMD应用
  • 原文地址:https://www.cnblogs.com/linbl/p/4681013.html
Copyright © 2020-2023  润新知