programing

JDBC를 사용하여 저장 프로시저에서 Oracle 테이블 유형 가져오기

css3 2023. 7. 4. 22:05

JDBC를 사용하여 저장 프로시저에서 Oracle 테이블 유형 가져오기

저는 JDBC를 사용하여 Oracle 저장 프로시저/함수에서 테이블 데이터를 가져오는 다양한 방법을 이해하려고 합니다.여섯 가지 방법은 다음과 같습니다.

  1. 절차스키마 수준 테이블 유형을 OUT 매개 변수로 반환
  2. 프로시저 패키지 수준 테이블 유형을 OUT 매개 변수로 반환
  3. 프로시저 패키지 수준 커서 유형을 OUT 매개 변수로 반환
  4. 함수:스키마 수준 테이블 유형 반환
  5. 함수패키지 수준 테이블 유형 반환
  6. 함수패키지 수준 커서 유형 반환

다음은 PL/SQL의 몇 가지 예입니다.

-- schema-level table type
CREATE TYPE t_type AS OBJECT (val VARCHAR(4));
CREATE TYPE t_table AS TABLE OF t_type;

CREATE OR REPLACE PACKAGE t_package AS
  -- package level table type
  TYPE t_table IS TABLE OF some_table%rowtype;
  -- package level cursor type
  TYPE t_cursor IS REF CURSOR;
END library_types;

-- and example procedures:
CREATE PROCEDURE p_1 (result OUT t_table);
CREATE PROCEDURE p_2 (result OUT t_package.t_table);
CREATE PROCEDURE p_3 (result OUT t_package.t_cursor);
CREATE FUNCTION f_4 RETURN t_table;
CREATE FUNCTION f_5 RETURN t_package.t_table;
CREATE FUNCTION f_6 RETURN t_package.t_cursor;

JDBC를 통해 3, 4, 6을 호출했습니다.

// Not OK: p_1 and p_2
CallableStatement call = connection.prepareCall("{ call p_1(?) }");
call.registerOutParameter(1, OracleTypes.CURSOR);
call.execute(); // Raises PLS-00306. Obviously CURSOR is the wrong type

// OK: p_3
CallableStatement call = connection.prepareCall("{ call p_3(?) }");
call.registerOutParameter(1, OracleTypes.CURSOR);
call.execute();
ResultSet rs = (ResultSet) call.getObject(1); // Cursor results

// OK: f_4
PreparedStatement stmt = connection.prepareStatement("select * from table(f_4)");
ResultSet rs = stmt.executeQuery();

// Not OK: f_5
PreparedStatement stmt = connection.prepareStatement("select * from table(f_5)");
stmt.executeQuery(); // Raises ORA-00902: Invalid data type

// OK: f_6
CallableStatement call = connection.prepareCall("{ ? = call f_6 }");
call.registerOutParameter(1, OracleTypes.CURSOR);
call.execute();
ResultSet rs = (ResultSet) call.getObject(1); // Cursor results

그래서 분명히, 저는 이해하는데 어려움을 겪고 있습니다.

  1. 저장 프로시저의 OUT 매개 변수에서 스키마 수준 및 패키지 수준 테이블 유형을 검색하는 방법
  2. 저장된 함수에서 패키지 수준 테이블 유형을 검색하는 방법

모든 사용자가 항상 테이블 형식 대신 커서를 사용하기 때문에 이에 대한 설명서를 찾을 수 없습니다.가능하지 않아서일까요?그러나 테이블 유형은 공식적으로 정의되고 사전 보기(최소한 스키마 수준 테이블 유형)를 사용하여 검색할 수 있기 때문에 선호합니다.

참고: 분명히, 저는 OUT 매개 변수와 패키지 레벨 테이블 유형을 반환하는 래퍼 함수를 작성할 수 있습니다.하지만 저는 깨끗한 해결책이 더 좋습니다.

Java에서 PLSQL 개체(사례 2 및 5 = 패키지 수준 개체)에 액세스할 수 없습니다. "오라클 저장 프로시저에서 어레이를 전달합니다."를 참조하십시오.그러나 SQL 유형(사례 1 및 4)에 액세스할 수 있습니다.

PL/SQL에서 Java로 OUT 매개 변수를 가져오려면 OracleCallableStatement를 사용하여 Tom Kyte의 스레드하나에 설명된 방법을 사용할 수 있습니다.VARCHAR 테이블 대신 Object 테이블을 검색하는 중이므로 코드에 추가 단계가 있습니다.

다음은 SQL 개체 표를 사용한 데모입니다. 먼저 설정하십시오.

SQL> CREATE TYPE t_type AS OBJECT (val VARCHAR(4));
  2  /
Type created

SQL> CREATE TYPE t_table AS TABLE OF t_type;
  2  /
Type created

SQL> CREATE OR REPLACE PROCEDURE p_sql_type (p_out OUT t_table) IS
  2  BEGIN
  3     p_out := t_table(t_type('a'), t_type('b'));
  4  END;
  5  /
Procedure created

실제 Java 클래스(사용)dbms_output.put_lineSQL에서 호출할 것이기 때문에 로그에 기록합니다.System.out.printlnJava에서 호출된 경우):

SQL> CREATE OR REPLACE
  2  AND COMPILE JAVA SOURCE NAMED "ArrayDemo"
  3  as
  4  import java.sql.*;
  5  import oracle.sql.*;
  6  import oracle.jdbc.driver.*;
  7  
  8  public class ArrayDemo {
  9     
 10     private static void log(String s) throws SQLException {
 11        PreparedStatement ps =
 12           new OracleDriver().defaultConnection().prepareStatement
 13           ( "begin dbms_output.put_line(:x); end;" );
 14        ps.setString(1, s);
 15        ps.execute();
 16        ps.close();
 17     }
 18  
 19     public static void getArray() throws SQLException {
 20  
 21        Connection conn = new OracleDriver().defaultConnection();
 22  
 23        OracleCallableStatement cs =
 24           (OracleCallableStatement)conn.prepareCall
 25           ( "begin p_sql_type(?); end;" );
 26        cs.registerOutParameter(1, OracleTypes.ARRAY, "T_TABLE");
 27        cs.execute();
 28        ARRAY array_to_pass = cs.getARRAY(1);
 29  
 30        /*showing content*/
 31        Datum[] elements = array_to_pass.getOracleArray();
 32  
 33        for (int i=0;i<elements.length;i++){
 34           Object[] element = ((STRUCT) elements[i]).getAttributes();
 35           String value = (String)element[0];
 36           log("array(" + i + ").val=" + value);
 37        }
 38     }
 39  }
 40  /
Java created

이제 그만하자꾸나:

SQL> CREATE OR REPLACE
  2  PROCEDURE show_java_calling_plsql
  3  AS LANGUAGE JAVA
  4  NAME 'ArrayDemo.getArray()';
  5  /

Procedure created

SQL> EXEC show_java_calling_plsql;

array(0).val=a
array(1).val=b

아래 항목도 사용할 수 있습니다.

public List<EmployeeBean> fetchDataFromSPForRM(String sInputDate) {

         List<EmployeeBean> employeeList = new ArrayList<EmployeeBean>();

         Connection dbCon = null;
         ResultSet data = null;
         CallableStatement cstmt = null;


         try {
                dbCon = DBUtil.getDBConnection();
                String sqlQuery = "{? = call PKG_HOLD_RELEASE.FN_RM_PDD_LIST()}";

                cstmt = dbCon.prepareCall(sqlQuery);

                cstmt.registerOutParameter(1, OracleTypes.CURSOR);

                cstmt.execute();

                data = (ResultSet) cstmt.getObject(1);              

                    while(data.next()){
                        EmployeeBean employee = new EmployeeBean();

                        employee.setEmpID(data.getString(1));
                        employee.setSubBusinessUnitId((Integer)data.getObject(2));
                        employee.setMonthOfIncentive((Integer)data.getObject(3));
                        employee.setPIPStatus(data.getString(5));
                        employee.setInvestigationStatus(data.getString(6));
                        employee.setEmpStatus(data.getString(7));
                        employee.setPortfolioPercentage((Integer)data.getObject(8));
                        employee.setIncentive((Double)data.getObject(9));
                        employee.setTotalSysemHoldAmt((Double)data.getObject(10));
                        employee.setTotalManualHoldAmt((Double)data.getObject(11));

                        employeeList.add(employee);
                    }

            } catch (SQLException e) {
                e.printStackTrace();
            }finally{
                try {

                    if(data != null){

                            data.close();               
                            data = null;
                    }
                    if(cstmt != null){

                        cstmt.close();
                        cstmt = null;
                    }
                    if(dbCon != null){

                            dbCon.close();              
                            dbCon = null;
                    }

                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }


        return employeeList;                
     }

언급URL : https://stackoverflow.com/questions/6410452/fetch-oracle-table-type-from-stored-procedure-using-jdbc