CallableStatement + registerOutParameter + multiple row result

前端 未结 2 1846
傲寒
傲寒 2020-12-21 11:53

I\'ve got a SQL statement of the form:

BEGIN\\n 
UPDATE tab 
SET stuff
WHERE stuff
RETURNING intA, intB, stringC
INTO ?,?,?

I\'ve registere

2条回答
  •  [愿得一人]
    2020-12-21 12:19

    To build upon what Luke Woodward answered and to refine my previous answer, you can create an Oracle type, use it to temporarily store data, and then return a sys_refcursor with your updates.

    Create the new type:

    CREATE OR REPLACE TYPE rowid_tab AS TABLE OF varchar2(30);
    

    Create the database function:

    CREATE OR REPLACE
    FUNCTION update_tab
    RETURN sys_refcursor
    IS
        ref_cur sys_refcursor;
        v_tab rowid_tab;
    BEGIN
        UPDATE tab 
        SET intA = intA+2
          , intB = intB*2
          , stringC = stringC||' more stuff.'
        RETURNING ROWID
        BULK COLLECT INTO v_tab;
    
        OPEN ref_cur FOR 
            WITH DATA AS (SELECT * FROM TABLE(v_tab))
            SELECT intA, intB, stringC
            FROM tab
            where rowid in (select * from data);
        RETURN ref_cur;
    END;
    

    Now, call the function in your java:

    import java.math.BigDecimal;
    import java.util.Arrays;
    import java.sql.*;
    import oracle.sql.*;
    import oracle.jdbc.*;
    
    public class StructTest {    
        public static void main(String[] args) 
            throws Exception 
        {   
            System.out.println("Start...");
    
            ResultSet results = null;
            Connection c = DriverManager.getConnection( "jdbc:oracle:thin:@localhost:1521:xe", "scott", "tiger");
            c.setAutoCommit(false);        
    
            String sql = "begin ? := update_tab(); end;";
            System.out.println("sql = "+sql);
            CallableStatement stmt = c.prepareCall(sql);        
            /* Register the out parameter. */
            System.out.println("register out param");
            stmt.registerOutParameter(1, OracleTypes.CURSOR);
            // get the result set
            stmt.execute();
            results = (ResultSet) stmt.getObject(1);
            while (results.next()){
                System.out.println("intA: "+results.getString(1)+", intB: "+results.getString(2)+", stringC: "+results.getString(3));
            }
            c.rollback();        
            c.close();    
        }
    }
    

    With my test data, I got the following results:

    intA: 3, intB: 4, stringC: a more stuff.
    intA: 6, intB: 10, stringC: C more stuff.
    intA: 3, intB: 4, stringC: a more stuff.
    

提交回复
热议问题