sql >> データベース >  >> RDS >> Oracle

Javaクラスからテーブルタイプとしてパラメータなしでプロシージャを呼び出す方法

    これは不可能です。表によるPL/SQL索引へのアクセスを参照してください:

    Oracle JDBCは、要素タイプとしてRAW、DATE、およびPL /SQLRECORDをサポートしていません。

    私はおそらく次のようなカスタム(パッケージではなくグローバル)オブジェクトタイプを使用します:

    CREATE TYPE t_all_record AS OBJECT (
      x_object_type_id        number,
        x_object_name           varchar2(100),
        x_object_id             varchar2(70),
        x_audit_timestamp       timestamp(6),
        x_payload               clob
    )
    /
    CREATE TYPE t_all_records IS TABLE OF t_all_record
    /
    

    パッケージ内のタイプのテーブル(tt_all_tabではなくt_all_records)を参照し、そのように入力します

    procedure get_data_Q1(x_object_id in varchar2 , x_all_type out t_all_records )
    AS
    begin
        SELECT t_all_record(O.object_type_id,O.object_name,O.object_id,A.audit_timestamp,P.payload)
        BULK COLLECT INTO x_all_type
        FROM APPLICATION APP, EXCEPTIONS E,MASTER_AUDIT A,MODULE_TYPE M,OBJECT_TYPE O,PAYLOAD P 
        WHERE ( A.MODULE_TYPE_ID = M.MODULE_TYPE_ID ) AND ( M.APPLICATION_ID = APP.APPLICATION_ID ) AND ( A.OBJECT_TYPE_ID = O.OBJECT_TYPE_ID ) AND ( O.OBJECT_ID = x_object_id )
    end get_data_Q1;
    

    結果は次のようにJavaから使用できます:

    package tests.jdbc;
    
    import java.sql.Array;
    import java.sql.CallableStatement;
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.ResultSetMetaData;
    import java.sql.Struct;
    import java.sql.Types;
    
    import oracle.sql.StructDescriptor;
    
    public class OracleTableOfResult {
        public static void main(String...a) throws Exception {
            Class.forName("oracle.jdbc.OracleDriver");
            Connection connection = DriverManager.getConnection("jdbc:oracle:thin:<USER>/<PASS>@<DATABASEHOST>:1521:<SERVICE>");
    
            final String typeName = "T_ALL_RECORD";
            final String typeTableName = "T_ALL_RECORDS";
    
            // Get a description of your type (Oracle specific)
            final StructDescriptor structDescriptor = StructDescriptor.createDescriptor(typeName.toUpperCase(), connection);        
            final ResultSetMetaData metaData = structDescriptor.getMetaData();
    
            // Call the procedure (or whatever else) that returns the table of a custom type
            CallableStatement cs = connection.prepareCall("{call ult_pkg.get_data_Q1(?, ?)}");
            cs.setString(1, "the_id");
            // Result is an java.sql.Array...
            cs.registerOutParameter(2, Types.ARRAY, typeTableName);     
            cs.execute();
    
            // ...who's elements are java.sql.Structs
            Object[] data = (Object[]) ((Array) cs.getObject(2)).getArray();
            for(Object tmp : data) {
                Struct row = (Struct) tmp;
                // Attributes are index 1 based...
                int idx = 1;
                for(Object attribute : row.getAttributes()) {               
                    System.out.println(metaData.getColumnName(idx) + " = " + attribute);                                            
                    ++idx;
                }
                System.out.println("---");
            }
            cs.close();     
            connection.close();
        }
    }
    

    しかし、結局のところ、プリペアドステートメントとしてプレーンSQLステートメントでクエリを使用できる場合に努力する価値があるかどうかは疑問です…




    1. IIf()関数とIIf()ステートメント

    2. 大規模な.patch_storage

    3. mysqlはレコード作成タイムスタンプを自動的に保存します

    4. SQLiteの結果をテーブルとしてフォーマットする方法