Java在sql WHERE子句中将值传递给IN

时间:2018-01-13 12:30:17

标签: java sql oracle jdbc where-in

我有像

这样的SQL查询
(sqlQuery)
SELECT *
FROM table1
WHERE to_char(id) in (?)

然后在我准备好的陈述中

preparedStatement ps = new preparedStatemend(sqlQuery)
ps.setString(1,param);

其中我的参数是一个看起来像param = '12','34', '444'

的字符串链

现在,我认为当我执行它时,一切都会好的,但事实并非如此,我得到的错误就像ORA 01460未实现或不合理的转换。

那么,如何将我的参数传递给sql查询中的几个valuse进入IN子句?

2 个答案:

答案 0 :(得分:1)

首先,您应该知道IN子句中的数据存在限制。因此,如果要将大量逗号分隔值作为IN子句的参数(绑定变量)传​​递,则应该管理其他内容。

现在,如果您的ID数量有限(例如,小于500左右,取决于id的大小,总共不能超过4000个字符),您可以使用regexp_substr和{{ 1}}在where子句中标记单个参数connect by的逗号分隔值:?

to_char(id) in (?)

当您将字符串 SELECT REGEXP_SUBSTR(? ,'[^,]+', 1, LEVEL) FROM dual CONNECT BY REGEXP_SUBSTR(? , '[^,]+', 1, LEVEL) IS NOT NULL 作为参数传递时,它会将它们标记为行:

  

'12'

     

'34'

     

'444'

理论上,您可以通过以下方式更改查询:

"'12','34', '444'"

以这种方式,如果SELECT * FROM table1 WHERE to_char(id) in ( SELECT REGEXP_SUBSTR(? ,'[^,]+', 1, LEVEL) FROM dual CONNECT BY REGEXP_SUBSTR(? , '[^,]+', 1, LEVEL) IS NOT NULL ) 的大小很大,那么由于每条记录的转化table1,性能会非常糟糕。

最好转换id子句的有限数量的参数以提高性能:

IN

并且在你的java代码中你应该传递字符串SELECT * FROM table1 WHERE id in ( SELECT REGEXP_SUBSTR(? ,'[^,]+', 1, LEVEL) FROM dual CONNECT BY REGEXP_SUBSTR(? , '[^,]+', 1, LEVEL) IS NOT NULL ) 作为参数(每个id周围没有单引号)。

您应该知道此解决方案未针对大量ID进行优化。但是,它会使"12,34, 444"子句的参数数量动态化。

希望这有帮助。

答案 1 :(得分:0)

您必须为IN子句的每个可能值指定?

例如,如果IN子句中有4个选项,则:

to_char(id) in (?)

应该是:

to_char(id) in (?, ?, ?, ?) 

你还应该通过连续递增param的索引来设置每个参数:

所以这个:

ps.setString(1,param);

应该是:

int index = 1;
for( String s : inValues ) {
   ps.setString(index++, s); 
}