我正在针对包含大量客户数据的数据库运行此MySQL查询。查询很大,所以我会删除部分。我们使用的是5.1.45-51-log Percona SQL Server,这是一个非常常见的MySQL版本。
select distinct * " +
"from customer_contact_preferences prefs " +
...
"join re_account_attribute uaa on uaa.account_id = ua.id " +
"where ... " +
...
"and uaa.attribute_key = 'R_GROUP' " +
//"and uaa.attribute_value in ( ? ) " + //PROBLEM HERE
"order by customer_contact_id)"
uaa.attribute值的参数是'1','2',3'。
在代码中,我们使用org.springframework.jdbc.core.simple.SimpleJDBCDaoSupport.update()来调用此查询。 当它通过Spring在代码中调用时,它错误地返回0行。当我替换args(4个人检查我做了替换权),并在mysql命令行上运行它时,查询正确返回> 5行。如果我注释掉问题行,就像我上面所做的那样,我得到> 5并且实际上有太多行(这就是为什么我需要这个约束)。
该表描述如下:
| attribute_key | varchar(255) | NO | | NULL | |
| attribute_value | varchar(255) | NO | | NULL | |
我们可以存储任何类型的键/值对,不限于varchar或int。
无论如何,当你有一个字符串或字符串列表时,做“IN”有什么问题?谢谢。
答案 0 :(得分:1)
您无法将List或数组绑定到'?'。
你必须创建'?'对于SQL中的List或数组中的每个项目,然后单独绑定每个项目。
List<String> values = Arrays.asList(new String [] { "foo", "bar", "baz" });
StringBuilder sql = new StringBuilder();
sql.append("SELECT * FROM X WHERE ID IN (");
for (int i = 0; i < values.length; ++i)
{
sql.append('?');
if (i != values.length-1))
sql.append(',');
}
sql.append(")");
PreparedStatement ps = connection.prepareStatement(sql.toString());
for (int i = 0; i < values.length; ++i)
{
ps.setString(i+1, values[i]);
}
ResultSet rs = ps.executeQuery();
答案 1 :(得分:1)
只有使用命名参数而不是IN
时,Spring JDBC模板才支持参数化?
子句,请参阅12.7.3 Passing in lists of values for IN clause。所以,你需要
getSimpleJdbcTemplate().update("... IN (:params) ...",
Collections.singletonMap("params", ...));