我有一个sql过程,有3个IN和1个OUT参数。其中OUT参数具有用户定义的数据类型,这意味着它是一种类型的表,
所以我想从java类中获取此表类型输出。
我尝试通过创建一个实现java.sql.Struct
的java类并在CallableStatement
registerOutParameter作为java.sql.Struct
类型的一个支持bean中使用它来获得此功能,但是出现了错误。
实际上以下是我想要解决方案的情况。
在我的情况下,我希望保存500个或更多由Java类逐个保存的记录。但我想要Oracle进程,如果我们传递一些参数将数据插入到表中,那么该过程将逐个插入所有数据,如果在任何位置发生任何错误,那么该记录将进入一个用户定义的表类型对象管道行()。所以我想使用java类获取userdefined tabletype对象。
你对这类问题有什么想法吗?
答案 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中,这当前适用于OBJECT
和VARRAY
类型。有关详细信息,请参阅jOOQ manual