1

我有一个具有 3 IN 和 1 OUT 参数的 sql 过程。其中 OUT 参数具有用户定义的数据类型,这意味着它是一种表,所以我想从 java 类中获取此表类型的输出。我试图通过创建一个 java 类来实现这一点,该类通过registerOutParameter 作为typejava.sql.Struct在一个支持 bean 中实现并使用它,但出现错误。CallableStatementjava.sql.Struct

实际上,以下是我想要解决方案的情况。

就我而言,我想保存 500 条或更多记录,并通过 Java 类一一保存。但是我想要Oracle进程,如果我们传递一些用于将数据插入表中的参数,那么该过程会一一插入所有数据,并且如果在任何位置发生任何错误,那么该记录将进入一个用户定义的表类型对象使用管道行()。所以我想使用java类获取用户定义的tabletype对象。

你对这类问题有什么想法吗?

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();
}

在这种情况下,您不必为输出定义特殊的 oracle 集合类型,只需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 中,这目前适用于OBJECTVARRAY类型。有关更多信息,请参阅jOOQ 手册

于 2011-05-02T12:23:56.827 回答