不能在JDBC PreparedStatement中使用LIKE查询?

查询代码和查询:

ps = conn.prepareStatement("select instance_id, ? from eam_measurement where resource_id in (select RESOURCE_ID from eam_res_grp_res_map where resource_group_id = ?) and DSN like '?' order by 2"); ps.setString(1,"SUBSTR(DSN,27,16)"); ps.setInt(2,defaultWasGroup); ps.setString(3,"%Module=jvmRuntimeModule:freeMemory%"); rs = ps.executeQuery(); while (rs.next()) { bla blah blah blah ... 

返回一个空ResultSet

通过基本的调试我发现它的第三个绑定是问题,即

 DSN like '?' 

我尝试了各种各样的变化,其中最明智的似乎是使用:

 DSN like concat('%',?,'%') 

但这不起作用,因为我错过了连接字符串两侧的'所以我尝试:

 DSN like ' concat('%',Module=P_STAG_JDBC01:poolSize,'%') ' order by 2 

但我似乎无法找到一种方法让他们参与其中。

我错过了什么?

首先, PreparedStatement占位符(那些?事物)仅用于列值 ,不用于表名,列名,SQL函数/子句等。 最好使用String#format() 。 其次,你不应该引用像'?'这样的占位符 ,它只会使最终查询失真。 PreparedStatement设置器已经为您执行引用(和转义)作业。

这是修复的SQL:

 private static final String SQL = "select instance_id, %s from eam_measurement" + " where resource_id in (select RESOURCE_ID from eam_res_grp_res_map where" + " resource_group_id = ?) and DSN like ? order by 2"); 

以下是如何使用它:

 String sql = String.format(SQL, "SUBSTR(DSN,27,16)"); // This replaces the %s. preparedStatement = connection.prepareStatement(sql); preparedStatement.setInt(1, defaultWasGroup); preparedStatement.setString(2, "%Module=jvmRuntimeModule:freeMemory%"); 

另见

  • Sun JDBC教程:使用准备语句
  • 格式字符串语法

你的陈述有两个问题。 您必须了解绑定变量的工作原理。 是否通过替换字符来处理查询? 与您的参数。 而是使用占位符编译语句,然后在执行期间,将参数的实际值提供给DB。

换句话说,您解析以下查询:

 SELECT instance_id, :p1 FROM eam_measurement WHERE resource_id IN (SELECT RESOURCE_ID FROM eam_res_grp_res_map WHERE resource_group_id = :p2) AND DSN LIKE '?' ORDER BY 2 

我很确定最后一个参数会被忽略,因为它是在一个分隔的字符串中。 即使它没有被忽略,因为Oracle不会绑定字符串中的参数(我很惊讶它没有引发任何错误,你是否捕获exception?),因此使用'周围'字符是没有意义的。

现在如果你更换你的DNS LIKE '?'DSN LIKE ? 并绑定"%Module=jvmRuntimeModule:freeMemory%"这将是有意义的,应该返回正确的行。

您仍然遇到第一个参数的问题,它不会按预期执行,即将执行的查询将等同于以下查询:

 SELECT instance_id, 'SUBSTR(DSN,27,16)' FROM ... 

这与…完全不同

 SELECT instance_id, SUBSTR(DSN,27,16) FROM ... 

如果您希望SUBSTR是动态的,我建议解析(= prepareStatement)以下查询:

 SELECT instance_id, SUBSTR(DSN,?,?) FROM eam_measurement WHERE resource_id IN (SELECT RESOURCE_ID FROM eam_res_grp_res_map WHERE resource_group_id = ?) AND DSN LIKE ? ORDER BY 2 

如果要在预准备语句中使用LIKE,并且还想在LIKE中使用%字符;

将准备好的语句写成通常“…. LIKE?….”并将参数值分配给问号使用

ps.setString(1, "%" + "your string value" + "%");

这将工作:)

省略'围绕? 。 没有'? 是参数的占位符。 有了它,它就是一个SQL字符串(即与Java中的"?"相同)。

然后你必须在Java端连接字符串; 您不能将SQL函数作为参数传递给查询; 只有基本值(如字符串,整数等),因为JDBC驱动程序会将参数转换为数据库所需的SQL类型,并且在此步骤中不能执行SQL函数。

你可以试试:

 String beforeAndAfter = "%" + yourVariable + "%"; 

这应该工作:

 "\'" + "?" + "\'" 
 PreparedStatement ps = con.prepareStatement( "select columname from tablename where LOWER(columnname) LIKE LOWER('"+var+"%')"); 

这里var是存储要搜索的值的变量…