我得到以下错误,但我无法理解原因:
org.springframework.jdbc.BadSqlGrammarException: PreparedStatementCallback;错误的SQL语法[UPDATE da_tracking SET ins_name = xyz,ins_dev_scripted = False WHERE ins_ID = 12];嵌套 异常是java.sql.SQLException:参数索引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() + "]");
你知道为什么吗?
我的删除&阅读方法工作。
答案 0 :(得分:4)
您看到的错误是因为您将变量传递到params
和types
数组,但您没有在查询中为这些绑定变量添加占位符:
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查询。在最好的情况下,如果有人在数据中放入一个奇怪的引用或转义字符,那么它将导致查询随机失败,在最坏的情况下,会导致一个主要的安全漏洞,这将危及您的系统。
答案 1 :(得分:1)
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() + "]");
这有用吗?