Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can we integrate Oracle RECORD TYPE with java Callable statement?

Is it true that RECORD type is not compatible with JDBC? the driver am using is OJDBC6.jar

Java Code:

dbStrategy.openConnection();
        WrappedConnectionJDK6 wrapped = (WrappedConnectionJDK6) dbStrategy.getConnection();
        OracleConnection oracleConnection = (OracleConnection) wrapped.getUnderlyingConnection();
        CallableStatement callableStatement = oracleConnection.prepareCall("{call XXX_Info_Utl_Pkg.get_order_admin(?,?,?,?,?)}");
        callableStatement.setInt(1, Integer.parseInt(orderNumber));
        callableStatement.registerOutParameter(2, OracleTypes.ARRAY, "XXX_INFO_UTL_PKG.SEAGRS_ORDER_REC");
        callableStatement.registerOutParameter(3, OracleTypes.NUMBER);
        callableStatement.registerOutParameter(4, OracleTypes.VARCHAR);
        callableStatement.registerOutParameter(5, OracleTypes.NUMBER);

And Oracle Code:

PROCEDURE get_order_admin(
            p_order_num_in IN NUMBER,
            p_order_admin_out OUT XXX_info_utl_pkg.seagrs_order_rec,
            p_error_code_out OUT PLS_INTEGER,
            p_error_msg_out OUT VARCHAR2,
            p_ret_status_out OUT PLS_INTEGER);


TYPE seagrs_order_rec
IS
    record
    (
        order_admin        VARCHAR2(10),
        contact_name       VARCHAR2(50),
        contact_email_addr VARCHAR2(100),
        contact_phone_num  VARCHAR2(30));

The error am facing here is -

Exception : invalid name pattern: XXX_INFO_UTL_PKG.SEAGRS_ORDER_REC

like image 369
musicar Avatar asked Dec 13 '25 22:12

musicar


2 Answers

While you cannot use JDBC directly to fetch your PL/SQL RECORD type, you can write an anonymous PL/SQL block and return the record into a local variable, which you can then decompose in its individual attributes as follows:

DECLARE
    rec XXX_info_utl_pkg.seagrs_order_rec;
BEGIN
    get_order_admin(?, rec, ?, ?, ?);
    ? := rec.order_admin;
    ? := rec.contact_name;
    ? := rec.contact_email_addr;
    ? := rec.contact_phone_num;
END;

You can now use the following JDBC code to call the procedure:

try (CallableStatement s = con.prepareCall(" ... previous PL/SQL block ...")) {
    s.setInt(1, Integer.parseInt(orderNumber));

    // Ordinary out parameters
    s.registerOutParameter(2, Types.NUMBER);
    s.registerOutParameter(3, Types.VARCHAR);
    s.registerOutParameter(4, Types.NUMBER);

    // Out parameters from your decomposed record
    s.registerOutParameter(5, Types.VARCHAR);
    s.registerOutParameter(6, Types.VARCHAR);
    s.registerOutParameter(7, Types.VARCHAR);
    s.registerOutParameter(8, Types.VARCHAR);

    s.execute();
    // Now, retrieve all the out parameters
}

I have recently blogged about this technique more in detail. The blog post also contains instructions about how you could automatically generate the anonymous PL/SQL blocks for all functions / procedures, that have record IN/OUT parameters.

like image 148
Lukas Eder Avatar answered Dec 15 '25 11:12

Lukas Eder


Record Type is not compatible with JDBC drivers:

It is not feasible for Oracle JDBC drivers to support calling arguments or return values of the PL/SQL RECORD, BOOLEAN, or table with non-scalar element types. However, Oracle JDBC drivers support PL/SQL index-by table of scalar element types.

READ THIS

like image 31
user2093576 Avatar answered Dec 15 '25 11:12

user2093576



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!