在准备语句中传递数组参数 - 获取“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
或者,您可以将每个输入值用作MySQL
中IN
函数的一组值。
更改您的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
列中存储值。它的数据类型是什么?
数据类型为字符串
取多值或单参数
你的意思是user1
和Administrator
可以作为两条不同的记录?
好的。你有一个编辑更正的答案。你可以照着做。以上是关于在准备语句中传递数组参数 - 获取“java.sql.SQLFeatureNotSupportedException”的主要内容,如果未能解决你的问题,请参考以下文章