此问题在此处已有答案:
How to load a large number of strings to match with oracle database?(3个答案)
5年前关闭。
我正在尝试通过执行 createArrayOf 将数组传递给准备好的语句
val array = Array("1165006001","1165006002")
val sqlArray = con.createArrayOf("VARCHAR",array) // getting the exception here
val prep = con.prepareStatement("select * from SOA_WEB_USER.VOPEX where CMF_PPK_NBR in (?)")
prep.setArray(1,sqlArray)
val rs = prep.executeQuery()
while (rs.next()) {
println(rs.getObject(1))
}
字符集
但是createArrayOf方法抛出一个错误
Exception thread "main" java.sql.SQLFeatureNotSupportedException:Unsupported feature
at Oracle.jdbc.driver.PhysicalConnection.createArrayOf(PhysicalConnection.java:8707)
at com.testpackage.Main$.main(Main.scala:109)
at com.testpackage.Main.main(Main.scala)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)
型
我正在使用ojdbc7.jar进行jdbc连接。有什么我可以做不同的传递数组到准备好的语句?
3条答案
按热度按时间bvhaajcl1#
Oracle数据库JDBC驱动程序不支持Connection.createArrayOf,因为Oracle数据库不支持匿名数组类型。类型ARRAY OF FOO是一个匿名类型。数组型别没有名称,但基底型别有名称。Oracle数据库不支持匿名数组类型。必须定义命名类型
字符串
然后,可以通过调用
型
Edit:正如@gouessej在评论中提到的,您甚至可以在Oracle Database Data Cartridge扩展中使用built-in类型。更简单的是:
型
hmmo2u0o2#
我不打算回答你提出的问题(“我如何将数组传递给准备好的语句”),因为即使你能弄清楚如何传递数组,你的代码很可能仍然无法工作。
问题是,对于JDBC,您不能将两个值
("1165006001","1165006002")
的数组传递到查询中字符串
并期望它被数据库解释为
型
在我看来是你想要的
如果可以传入数组,则查询将返回列
CMF_PPK_NBR
包含具有这两个值的嵌套表的所有行。Oracle会将数组解释为一个值,而不是两个值。我猜该列的类型是VARCHAR2
,因此当Oracle试图将字符串数组与单个字符串进行比较时,您只会得到一个类型错误。如果要在
IN
子句中传递多个值,那么最简单的方法是构建一个带有许多?
标记的SQL字符串,并分别为参数设置值。换句话说,对于上面的示例,两个参数的SQL字符串将是型
你会有两个
prep.setString(...)
的调用,每个数组元素一个。类似地,如果数组中有5个元素,您将构建一个带有5个?
标记的SQL字符串,并调用prep.setString(...)
5次,依此类推。wlsrxk513#
没有完全好的方法来做到这一点,但仍然存在两个合理的方法。
使用手工创建的
in (?,...)
子句。solution is explained here。其思想是添加与三个数组元素一样多的
?
,并单独绑定每个元素。这给了你安全感,因为值将被正确地转换、转义等。这就违背了准备语句的目的,除非数组的大小通常相同。
如果数组中有很多项,也可能超出允许的查询长度。
使用强制转换并将数组作为字符串传递。
解决方案(对于PL/SQL)是explained here,但适用于一般的SQL语句。它可以归结为使用一个子句,如
字符串
这里的参数作为
varchar2
传递,就像"1, 2, 3"
一样,被解析为内存中的表,并从in
子句中选择。这使您可以有一个固定长度的查询,并可能有效地重用预准备语句。它还允许你在数组中传递大量的元素。
它,OTOH,* 要求你将数据连接并作为字符串传递,* 这可能会导致 SQL注入。 如果你的数组值是数字,我仍然认为它是安全的。