我正在尝试从我的Java程序调用Oracle存储过程。我正在使用JDBC和Spring的StoredProcedure。一些参数是用户定义的类型,我需要知道如何传递它们。
特别是我应该在参数图中指定哪种类型(即java.sql.Types.*
中的哪一种)?我应该使用什么Java类型?问题类型定义如下:
type MyDoubles as varray(50000) of double precision
type MyStrings as varray(50000) of varchar2(2000)
答案 0 :(得分:1)
Google首次点击似乎展示了如何绑定VARRAY类型的参数:http://www.devx.com/tips/Tip/22034。本文档中的示例使用预准备语句,但对于存储过程,它应该使用相同的。
这是一个显示基本概念的摘录:
String arrayElements[] = { "Test3", "Test4" }; PreparedStatement ps = conn.prepareStatement ("insert into sample_varray_table values (?)"); ArrayDescriptor desc = ArrayDescriptor.createDescriptor("STRING_VARRAY", conn); ARRAY newArray = new ARRAY(desc, conn, arrayElements); ((OraclePreparedStatement)ps).setARRAY (1, newArray); ps.execute ();
这里要澄清一些FQDN:
答案 1 :(得分:0)
为什么用户传递 50,000个双打和字符串实例 - 所以Oracle可以执行计算?
这似乎是我的倒退。如果用户已经拥有那一天,也许Java可以执行该计算。如果您真的希望Oracle这样做,我会说数据应该已经驻留在数据库中而不是传入。
两者都不是java.sql.Type.ARRAY吗?
答案 2 :(得分:0)
您确实可以使用Philipp建议的Oracle JDBC驱动程序中的对象。大多数用户最终创建实用程序方法来包装该逻辑。或者他们使用Spring映射器类。不过,还有很多手工工作要做。
另一种方法是使用即将开发的jOOQ版本1.5.4 - 我正在开发的开源库 - 其中数组得到统一支持。所以当你有你的类型时:
type MyDoubles as varray(50000) of double precision
type MyStrings as varray(50000) of varchar2(2000)
然后jOOQ会生成诸如
之类的类public class MyDoubles extends ArrayRecordImpl<Double> { /* ... */ }
public class MyStrings extends ArrayRecordImpl<String> { /* ... */ }
您的存储过程可能如下所示:
PROCEDURE MY_PROC1 (d IN MyDoubles, s IN MyStrings);
PROCEDURE MY_PROC2 (d IN MyDoubles, s OUT MyStrings);
PROCEDURE MY_PROC3 (d OUT MyDoubles, s OUT MyStrings);
jOOQ会生成另一个Java类,例如
public class Procedures {
// Invoke procedure MY_PROC on JDBC Connection c with VARRAY arguments
public static void myProc1(Connection c, MyDoubles d, MyStrings s);
// The OUT parameter is mapped to a method return value
public static MyStrings myProc2(Connection c, MyDoubles d);
// MyProc3 is a wrapper for both OUT parameters
public static MyProc3 myProc3(Connection c);
}
使用生成的代码工件,使用UDT调用存储过程,VARRAY参数就像它可以一样简单。通过源代码生成,您可以在数据库模式中更改对象(例如,您的类型或过程),并且您的Java类将立即反映该更改。
查看http://www.jooq.org/manual/META/PROCEDURE/上的手册了解更多详情