在某些参数类型是用户定义的情况下,如何使用 JDBC/Spring 调用 Oracle 存储过程?
Posted
技术标签:
【中文标题】在某些参数类型是用户定义的情况下,如何使用 JDBC/Spring 调用 Oracle 存储过程?【英文标题】:How can I call an Oracle stored procedure with JDBC/Spring where some of the parameter types are user defined? 【发布时间】:2010-08-17 09:32:08 【问题描述】:我正在尝试从我的 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)
【问题讨论】:
【参考方案1】:Google 中的第一个热门似乎展示了如何绑定 VARRAY 类型的参数:http://www.devx.com/tips/Tip/22034。本文档中的示例使用预准备语句,但对于存储过程,它的工作方式应该相同。
这是一个显示基本概念的摘录:
字符串数组元素[] = "Test3", "Test4" ; PreparedStatement ps = conn.prepareStatement("插入到 sample_varray_table 值 (?)"); ArrayDescriptor desc = ArrayDescriptor.createDescriptor("STRING_VARRAY", conn); 数组 newArray = new ARRAY(desc, conn, arrayElements); ((OraclePreparedStatement)ps).setARRAY (1, newArray); ps.execute();
为了澄清这里有几个 FQDN:
oracle.sql.ArrayDescriptor oracle.sql.ARRAY oracle.jdbc.OraclePreparedStatement【讨论】:
【参考方案2】:为什么用户传递 50,000 个双精度和字符串实例 - 以便 Oracle 可以执行计算?
这对我来说似乎倒退了。如果用户已经拥有了一整天的时间,也许 Java 可以执行该计算。如果您真的希望 Oracle 这样做,我会说数据应该已经驻留在数据库中而不是传入。
不会都是 java.sql.Type.ARRAY 吗?
【讨论】:
我能想到一个原因 - 在应用程序中构建数组,将数组传递给 PL/SQL 过程以使用 FORALL 执行批量 PL/SQL 操作。但是,我会使用TABLE OF
与 VARRAY(50000)
来获得灵活性,但这只是我自己。
数据库可以执行哪些在服务器端无法完成的操作,而不会产生来回的网络流量成本?如果这是一个长时间运行的过程,我希望它是异步的,无论它在哪里完成。仍然没有意义。【参考方案3】:
您确实可以按照 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/了解更多详情
【讨论】:
以上是关于在某些参数类型是用户定义的情况下,如何使用 JDBC/Spring 调用 Oracle 存储过程?的主要内容,如果未能解决你的问题,请参考以下文章