【问题标题】:MySQL Query fails in my App, but succeeds in MySQL Command Line ToolMySQL Query 在我的应用程序中失败,但在 MySQL 命令行工具中成功
【发布时间】:2010-11-06 17:11:32
【问题描述】:

我正在对包含大量客户数据的数据库运行此 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 或 ints。

无论如何,当您有一个字符串或字符串列表时,执行“IN”有什么问题?谢谢。

【问题讨论】:

    标签: spring mysql jdbc


    【解决方案1】:

    仅当您使用命名参数而不是 ?s 时,Spring JDBC 模板才支持参数化 IN 子句,请参阅 12.7.3 Passing in lists of values for IN clause。所以,你需要

    getSimpleJdbcTemplate().update("... IN (:params) ...", 
        Collections.singletonMap("params", ...));
    

    【讨论】:

      【解决方案2】:

      您不能将列表或数组绑定到“?”。

      您必须创建一个“?”为 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();
      

      【讨论】:

      • 谢谢这是很棒的信息。我需要一种兼容弹簧的方式,请参阅下面的解决方案。
      猜你喜欢
      • 1970-01-01
      • 2015-02-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-23
      • 1970-01-01
      • 1970-01-01
      • 2014-08-18
      相关资源
      最近更新 更多