【问题标题】:Trouble with PreparedStatement that uses union of selects query and IN CLAUSE使用选择查询和 IN CLAUSE 联合的 PreparedStatement 出现问题
【发布时间】:2011-08-01 12:47:30
【问题描述】:

我写了一个查询表格:

select .... where x.y in (?) union select .... where p.y in (?) and a.b not in (?) 

问号表示我在运行时使用preparedStatement.setString() 方法放置多个值的位置(在IN 子句中动态放置值)。

执行此查询的结果集似乎忽略了联合子句之后的查询。 我在任何地方都没有例外。

我发布这个问题,只是想知道其他人是否遇到过这样的问题,就像这个链接建议UNION of multiple tables and preparedstatement not working 数据库是 Oracle 10g,以防万一。

【问题讨论】:

  • 我会怀疑“许多值”字符串被解释为单个字符串 - 因此与您的期望不匹配。感觉就像您想生成完整的 sql 字符串,然后将其作为执行立即类型操作发出。
  • 我采用这个查询模板。然后根据传入参数的数量,替换一个?每个 in 子句带有 n 个问号,然后调用 setString 正确的次数。我不明白您所说的“许多值字符串解释为单个字符串”是什么意思。能否请您详细说明。
  • 在这种情况下,您能否显示您对数据库执行的实际查询?
  • 抱歉,查询失败,因为 UNION 之后的第二个 IN 子句填充不正确。感谢大家的帮助。我真的应该更加小心。 :(

标签: java sql oracle jdbc prepared-statement


【解决方案1】:

您只能使用“?” 独立值的运算符。使用 String 来设置 IN 值你会得到...

SELECT * FROM TABLE WHERE ID IN (?)

...将被考虑...

SELECT * FROM TABLE WHERE ID IN ("1,2,3,4")

...在你的情况下。

如果您使用 JavaRanch 链接中的“选项 2”,它会像..

SELECT * FROM TABLE WHERE ID IN (1, 2, 3, 4)

...我相信这是您想要的,但是您将需要始终提供正好 4 个值。如果您的数量较少,您当然可以再次使用其中一个而不会产生不良影响,但如果您拥有更多的数量,那么您就不走运了。

我建议您做的是动态构造 PreparedStatement,使用尽可能多的 '?'因为你有参数,然后循环并设置它们。这样一来,您将需要动态查询与清理输入结合起来,避免任何 SQL 注入攻击。

【讨论】:

  • 感谢 JenEriC,但我想我在执行前在运行时用 IN(?,?,?) 替换了 IN(?)。我会仔细检查我的代码,并尝试使用简单数据的示例尖峰解决方案来确定。
【解决方案2】:

据我所知 - 您不能将 ? 用于 in 运算符 - 但可以很好地支持 union

您是否尝试将in 替换为=?或者删除union 并检查它是否解决了问题?

【讨论】:

  • 我不同意。这个链接似乎表明我们可以使用?对于 IN 运算符。看看选项 2 中的查询。javaranch.com/journal/200510/Journal200510.jsp#a2
  • Abhijeet,请更仔细地查看该文章中的选项 2。它为列表中的每个值使用一个绑定变量:id IN (?, ?, ?)。您似乎正在尝试对整个列表使用单个绑定变量:x.y in (?),并且您说您在运行时“放置多个值”。这行不通;绑定变量表示单个值,而不是值列表。可能您正在有效地绑定像'1,2,3' 这样的字符串。
  • 请阅读您上面的评论。我最初的解释可能不正确——但如果您发布的字符串在提交到数据库之前在 Java 中被操作,那么您应该发布正在执行的实际查询。
猜你喜欢
  • 2023-03-28
  • 1970-01-01
  • 1970-01-01
  • 2022-07-23
  • 2023-04-06
  • 1970-01-01
  • 2010-11-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多