1

3 つの IN パラメーターと 1 つの OUT パラメーターを持つ 1 つの SQL プロシージャがあります。OUTパラメータにはユーザー定義のデータ型があり、これはテーブルの1つのタイプであることを意味するため、Javaクラスからこのテーブルタイプの出力を取得したいと考えています。typeとして registerOutParameterjava.sql.Structによって実装され、1 つのバッキング Bean で使用される1 つの Java クラスを作成して、これを取得しようとしましたが、エラーが発生しました。CallableStatementjava.sql.Struct

実際、以下は私が解決策を求めている状況です。

私の場合、500 件以上のレコードを Java クラスで 1 つずつ保存して保存したいと考えています。しかし、代わりに、データをテーブルに挿入するためのパラメータを渡すと、プロシージャがすべてのデータを 1 つずつ挿入する Oracle プロセスが必要です。これにより、任意の位置でエラーが発生した場合、そのレコードは、パイプ行()。したがって、Javaクラスを使用してユーザー定義のテーブルタイプオブジェクトを取得したいと考えています。

このタイプの問題について何か考えはありますか?

4

2 に答える 2

2

複数の Oracle オブジェクト タイプを定義できます。Oracle オブジェクトの場合、それらは にマップされjava.sql.Structます。コレクションの場合(私が理解している限り、あなたが参照しているテーブルタイプのように)、それらはにマップされjava.sql.Arrayます。out パラメータを として登録するだけjava.sql.Arrayです。古い oracle JDBC ドライバー (10g) の場合は、型 (スキーマを含む) への完全な参照を使用することを忘れないでください。そうしないと、「無効な型」などのエラーが発生する可能性があります。

例:

stmt.registerOutParameter(4, Types.ARRAY, "SCHEMA.TABLE_TYPE");
stmt.execute();
Array array = stmt.getArray(4);

このようなコードがたくさんある場合は、eclipselink のアプローチを利用できます。

@Entity
@NamedStoredProcedureQueries({
    @NamedStoredProcedureQuery(
            name = "Company.getCompanies",
            procedureName = "SQL_PACKAGE.GET_COMPANIES",
            parameters = { 
                    @StoredProcedureParameter(queryParameter = "p_filter", direction = Direction.IN), 
                    @StoredProcedureParameter(queryParameter = "p_result", direction = Direction.OUT_CURSOR),
                    },
            resultClass = Company.class)
})
public class Company {

    @Id
    @Column(name = "COMPANY_NO")
    private Long companyNo;

    @Column(name = "COMPANY_NAME")
    private String companyName;

    public Long getCompanyNo() {
        return companyNo;
    }

    public String getCompanyName() {
        return companyName;
    }

}

そして、DAO でそのようなエンティティを使用します。

@Transactional(readOnly = true)
public List<Company> getCompanies(String filter) {
    EntityManager em = entityManagerProvider.get();
    Query query = em.createNamedQuery("Company.getCompanies");
    query.setParameter("p_filter", filter);
    return query.getResultList();
}

このようなシナリオでは、出力用に特別なオラクル コレクション タイプを定義する必要はなくref cursor、PL/SQL で返すだけです。

于 2011-05-01T18:02:14.493 に答える
1

私はjOOQの開発者であり、まさにこのような目的のために jOOQ を作成しました。jOOQ の完全な SQL サポートとは別に、ストアド プロシージャとユーザー定義型の両方に対して Java クラスを生成できます。ストアド プロシージャの呼び出しは、Java では次のようになります。

MyUserType result = Procedures.myProcedure(1, 2, 3);

Oracle では、これは現在、OBJECTandVARRAY型に適用されます。詳細については、jOOQ のマニュアルを参照してください。

于 2011-05-02T12:23:56.827 に答える