如何从java类中获取用户定义的sql过程参数

时间:2011-04-07 12:17:45

标签: java sql stored-procedures callable-statement

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

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

在我的情况下,我希望保存500个或更多由Java类逐个保存的记录。但我想要Oracle进程,如果我们传递一些参数将数据插入到表中,那么该过程将逐个插入所有数据,如果在任何位置发生任何错误,那么该记录将进入一个用户定义的表类型对象管道行()。所以我想使用java类获取userdefined tabletype对象。

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

2 个答案:

答案 0 :(得分:1)

您可以定义几个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集合类型,只需在PL / SQL中返回ref cursor

答案 1 :(得分:1)

我是jOOQ的开发人员,我为这些目的创建了jOOQ。除了jOOQ的完整SQL支持外,您还可以为存储过程和用户​​定义类型生成Java类。然后,您的存储过程调用将在Java中看起来像这样。

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

在Oracle中,这当前适用于OBJECTVARRAY类型。有关详细信息,请参阅jOOQ manual