【问题标题】:How to pass a List of Integer value with PreparedStatement如何使用 PreparedStatement 传递整数值列表
【发布时间】:2014-09-04 20:13:13
【问题描述】:

我尝试编写这样的代码在 MySql DB 上进行 SELECT

SELECT MESE,IMPORTO,ANNO FROM VISTASTATISTICHEMENSILI WHERE ANNO in(?)

所以,我想像这样传递一个整数值列表:

PreparedStatement stmt = db.prepareStatement(queryDettaglio);
Integer[] myArr = new Integer[2];
myArr[0] = 1;
myArr[1] = 2;
stmt.setArray(1, db.createArrayOf("INTEGER", myArr));  
ResultSet rs = stmt.executeQuery();

所以,当我尝试运行这段代码时,我遇到了这个错误:

DEBUG [AWT-EventQueue-0] (MyLog4J.java:45) - java.sql.SQLFeatureNotSupportedException
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
    at java.lang.Class.newInstance0(Class.java:357)
    at java.lang.Class.newInstance(Class.java:310)
    at com.mysql.jdbc.SQLError.notImplemented(SQLError.java:1332)
    at com.mysql.jdbc.JDBC4Connection.createArrayOf(JDBC4Connection.java:58)

什么时候修复?

警戒

【问题讨论】:

标签: java mysql list prepared-statement


【解决方案1】:

您不能将数组传递给 ?在准备好的声明中。这样做并避免所有注入攻击的正确方法是这样的:

StringBuilder idList = new StringBuilder()
for (int id : myArr) {
   if (idList.length() > 0) {
     idList.append(",");
   }
   idList.append("?");
}
PreparedStatement ps = con.prepareStement("SELECT MESE,IMPORTO,ANNO FROM VISTASTATISTICHEMENSILI WHERE ANNO in("+idList+");
for (int i = 0; i < myArr.length; i++) {
  ps.setInt(i+1,myArr[i]);
}

基本上,您正在构建一个包含正确数量的准备好的语句?标记,然后设置参数。

因为 myArr 被声明为 Integer[] 数组,您也可以这样做:

StringBuilder idList = new StringBuilder()
for (int id : myArr) {
   if (idList.length() > 0) {
     idList.append(",");
   }
   idList.append(id);
}
Statement stmt = con.createStatement();
stmt.executeQuery("SELECT MESE,IMPORTO,ANNO FROM VISTASTATISTICHEMENSILI WHERE ANNO in("+idList+");

注入没有问题,因为整数不可能有注入字符(如果有,它们就不是整数)

【讨论】:

    【解决方案2】:

    尝试在 for 循环中手动绑定 n 个整数。

    在此之前,您应该创建 ?,?,...,? sql中的模式。 祝你好运。

    import org.apache.commons.lang3.StringUtils;
    
    /*
     * example: for n=4 creates pattern: ?,?,?,?
     */
    public String createInListPattern(int n) {
        return StringUtils.repeat("?", ",", n);
    }
    
    public void doSelect(Integer[] myArr, Connection conn) {
        int size = myArr.length;
        String sql = "SELECT MESE,... FROM TABLE WHERE ANNO in ("
                        + createInListPattern(size) + ")";
    
        // be sure to properly handle sql exceptions
        PreparedStatement stmt = conn.prepareStatement(sql);
    
        // bind parameters
        for (int i = 0; i < size; i++) {
            stmt.setInt(i + 1, myArr[i]);
        }
    
        // execute query
        ResultSet rs = stmt.executeQuery();
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-13
      • 2018-07-04
      • 2012-09-26
      • 1970-01-01
      • 2022-12-12
      • 1970-01-01
      相关资源
      最近更新 更多