MySQL查询在我的应用程序中失败,但在MySQL命令行工具中成功

时间:2010-11-06 17:11:33

标签: spring mysql jdbc

我正在针对包含大量客户数据的数据库运行此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”有什么问题?谢谢。

2 个答案:

答案 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", ...));