【问题标题】:nested exception is java.sql.SQLException: Invalid parameter index 1嵌套异常是 java.sql.SQLException: Invalid parameter index 1
【发布时间】:2012-08-29 15:32:17
【问题描述】:

我得到以下错误,但我不明白为什么:

org.springframework.jdbc.BadSqlGrammarException: PreparedStatementCallback;错误的 SQL 语法 [UPDATE da_tracking SET ins_name= xyz, ins_dev_scripted = False WHERE ins_ID = 12];嵌套的 异常是 java.sql.SQLException: Invalid parameter index 1。

------------------------ dao class-----
public int save(DboBean record) {
        // TODO Auto-generated method stub
        String sql = "UPDATE da_tracking"
                    + " SET ins_name= " + record.getDboDevName()+ "," 
                    + " ins_dev_scripted = " + record.getDevScripted()
                    + " WHERE ins_ID = " + record.getDboId();
        Object[] params = new Object[] {record.getDboDevName(), record.getDevScripted()};
        int[] types = new int[]{Types.VARCHAR, Types.BIT};
        return jdbcTemplate.update(sql, params, types);
    }
----------------------------Junit-----
bean.setDboDevName("xyz");
bean.setDboId(12);
int rowsAffected =  objDao.save(bean);

    System.out.println("Object is updated [" + bean.getDboId() + ", " + bean.getDboDevName() + 
            ", " + bean.getDevScripted() + "]");

你知道为什么吗? 我的删除和读取方法有效。

【问题讨论】:

    标签: java


    【解决方案1】:

    您看到的错误是因为您将变量传递到 paramstypes 数组,但您没有在查询中为这些绑定变量放置占位符:

    String sql = "UPDATE da_tracking"
                + " SET ins_name= ?," 
                + " ins_dev_scripted = ?"
                + " WHERE ins_ID = ?"
    Object[] params = new Object[] {record.getDboDevName(), record.getDevScripted(), record.getDboId()};
    int[] types = new int[]{Types.VARCHAR, Types.BIT, Types.INTEGER};
    return jdbcTemplate.update(sql, params, types);
    

    在内部,Spring 正在做这样的事情:

    PreparedStatement stmt = conn.prepareStatement("...your sql...");
    stmt.setString(1, dboDevName); // this will fail, since there is no bind variable
                                   // with index 1
    ...
    

    您绝不应该通过连接外部数据来构建 SQL 查询。在最好的情况下,如果有人在数据中加入奇怪的引号或转义字符,查询会随机失败,在最坏的情况下,会导致一个重大的安全漏洞,从而危及您的系统。

    【讨论】:

      【解决方案2】:
      public int save(DboBean record) {
      
              String sql = "UPDATE da_tracking"
                          + " SET ins_name= ?"+"," 
                          + " ins_dev_scripted = ?" 
                          + " WHERE ins_ID = ?";
              Object[] params = new Object[] {record.getDboDevName(), record.getDevScripted(), record.getDboId()};
              int[] types = new int[]{Types.VARCHAR, Types.BIT, Types.INTEGER}; // Change 3rd parameter type here
              return jdbcTemplate.update(sql, params, types);
          }
      
      ----------------------------Junit-----
      bean.setDboDevName("xyz");
      bean.setDboId(12);
      int rowsAffected =  objDao.save(bean);
      
          System.out.println("Object is updated [" + bean.getDboId() + ", " + bean.getDboDevName() + 
                  ", " + bean.getDevScripted() + "]");
      

      这行得通吗?

      【讨论】:

      • 您应该使用绑定变量(参数化查询)是正确的,但这不是此错误的根源。你是对的,变量(可能只有ins_name)需要被引用,但是SQL解析器还没有深入解析查询。
      • 太棒了。 :) 您能否投票和/或将其标记为答案?谢谢。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-08-13
      • 1970-01-01
      • 2019-10-26
      • 1970-01-01
      • 1970-01-01
      • 2018-05-28
      • 2020-07-05
      相关资源
      最近更新 更多