在准备语句中传递数组参数 - 获取“java.sql.SQLFeatureNotSupportedException”

Posted

技术标签:

【中文标题】在准备语句中传递数组参数 - 获取“java.sql.SQLFeatureNotSupportedException”【英文标题】:Passing array parameter in prepare statement - getting "java.sql.SQLFeatureNotSupportedException" 【发布时间】:2014-08-23 01:55:27 【问题描述】:

我在准备语句中遇到错误 java.sql.SQLFeatureNotSupportedException。我正在使用 mysql 数据库。

下面是我的代码。

class tmp 
public static void main(String arg[]) 

    try 
        Class.forName("com.mysql.jdbc.Driver");
        Connection conn = DriverManager.getConnection(
                "jdbc:mysql://localhost/sample", "root", "root");
        PreparedStatement pst = conn
                .prepareStatement("select * from userinfo where firstname in(?)");

        String[] Parameter =  "user1", "Administrator" ;
        Array sqlArray = conn.createArrayOf("VARCHAR", Parameter);
        pst.setArray(1, sqlArray);
        ResultSet rs = pst.executeQuery();
        while (rs.next()) 
            System.out.println(rs.getInt(1));
        
     catch (Exception e) 
        e.printStackTrace();
        
    

【问题讨论】:

【参考方案1】:

将 List 转换为逗号分隔的 String 并使用它。

Class Tmp 
        public static void main(String arg[]) 

            try 
                Class.forName("com.mysql.jdbc.Driver");
                Connection conn = DriverManager.getConnection(
                        "jdbc:mysql://localhost/sample", "root", "root");

                // Consider this list is already constructed
                List<String> parameter = new ArrayList<String>();
                parameter.add("user1");
                parameter.add("Administrator");

                String parameterStr = "'" + String.join("','", parameter) + "'";
                PreparedStatement pst = conn.prepareStatement("select * from userinfo where firstname in(" + parameterStr + ")");

                ResultSet rs = pst.executeQuery();
                while (rs.next()) 
                    System.out.println(rs.getInt(1));
                
             catch (Exception e) 
                e.printStackTrace();
            
        
    

【讨论】:

会不会是sql注入?【参考方案2】:

对于Mysql -

Mysql不能设置数组

您可以在循环中形成对 (?,?,..) 的查询,并以同样的方式设置值。

String[] Parameter =  "user1", "Administrator" ;
String query = "select * from userinfo where firstname in (";
String temp = "";

for(i = 0; i < Parameter.length; i++) 
  temp += ",?";


temp = temp.replaceFirst(",", "");
temp += ")";
query = query + temp;

PreparedStatement pst = conn.prepareStatement(query);

所以查询变成了

select * from userinfo where firstname in (?,?)

并使用循环传递值。

对于Oracle -

ArrayDescriptor arrayDescriptor = ArrayDescriptor.createDescriptor("CHAR_ARRAY", conn);
String[] Parameter =  "user1", "Administrator" ;
java.sql.Array sqlArray = new oracle.sql.ARRAY(arrayDescriptor, conn, content);
.
.
pstmt.setArray(1, sqlArray);

【讨论】:

您的答案是MySQL 还是Oracle 它给了我错误“java.lang.ClassCastException: com.mysql.jdbc.JDBC4Connection cannot be cast to oracle.jdbc.OracleConnection” 对不起,那是甲骨文。 Mysql 怎么做 我已经编辑了我的答案..以编程方式创建 (?,?...)【参考方案3】:

错误信息非常清楚。而MySQL 不支持自定义数据类型。

目前 MySQL 仅支持:

    Numeric Type Date and Time Type String Type

或者,您可以将每个输入值用作MySQLIN 函数的一组值。

更改您的JAVA 代码如下:

StringBuilder sbSql = new StringBuilder( 1024 );
sbSql.append( "select * from userinfo where firstname in(" );

for( int i=0; i < Parameter.length; i++ ) 
  if( i > 0 ) sbSql.append( "," );
  sbSql.append( " ?" );
 // for
sbSql.append( " )" );
PreparedStatement pst = conn.prepareStatement( sbSql.toString() );

for( int i=0; i < Parameter.length; i++ ) 
  pst.setString( i+1, Parameter[ i ] );
 // for

ResultSet rs = pst.executeQuery();

【讨论】:

您如何在firstname 列中存储值。它的数据类型是什么? 数据类型为字符串 取多值或单参数 你的意思是user1Administrator可以作为两条不同的记录? 好的。你有一个编辑更正的答案。你可以照着做。

以上是关于在准备语句中传递数组参数 - 获取“java.sql.SQLFeatureNotSupportedException”的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 jdbc 准备好的语句传递可变数量的参数?

从准备好的语句中获取数据

在准备好的语句参数中使用表列

php 超链接里的参数如何传递数组

spring MVC 怎么获取前端传递的数组参数

如何确定从我的 html 表单获取的输入值的数据类型,以便我可以使用它们在准备好的语句中绑定参数