Java SQL 数组和 Where...IN 列表中的准备语句问题

Java SQL Prepared Statement Issue with Array and Where... IN List

我有一个包含字符串的数组列表:

ArrayList<String> anrs = new ArrayList<>();

现在我将它们转换成一个 SQL 数组,如下所示:

final String[] data = anrs.toArray(new String[anrs.size()]);
final java.sql.Array sqlArray = connection.createArrayOf("varchar", data);

现在我想做一个准备好的声明:

statement = connection.createStatement();
String selectSQL = "SELECT * FROM rekopf INNER JOIN repos ON rekopf.rekopfnum=repos.Reposnum WHERE repos.reposart IN ?";
pstatement = connection.prepareStatement(selectSQL);
pstatement.setArray(1, sqlArray);
resultSet = pstatement.executeQuery();

但是我得到了这个错误:

net.ucanaccess.jdbc.UcanaccessSQLException: UCAExc:::4.0.1 unexpected token: ? required:

此行出现错误:pstatement = connection.prepareStatement(selectSQL);

在这种情况下我的问题是什么?提前致谢。


更新当我这样尝试时:

pstatement.setArray(1, connection.createArrayOf("varchar", data));

然后我得到这个错误

net.ucanaccess.jdbc.UcanaccessSQLException: UCAExc:::4.0.1 incompatible data type in conversion

问题可能在于使用 ? 作为占位符。

尝试...WHERE repos.reposart IN (?)

已找到 here

是像别人说的?是问题。

在这种情况下我是这样做的:

String selectSQL = "SELECT * FROM rekopf INNER JOIN repos ON rekopf.rekopfnum=repos.Reposnum WHERE repos.reposart IN (";

            int count = 0;

            for (String anr : anrs){
                selectSQL += "'"+anr+"'";
                count++;
                if (count < anrs.size()){
                    selectSQL += ",";
                }
            }

            selectSQL += ")";

这不太好。但在这种情况下超级高效。

谢谢。

java.sql.Array 不等同于 java 任何数据类型的数组。一些数据库内置了对集合和记录类型的支持(例如 Oracle 中的 Varray)。 java.sql.Array 可以方便地从客户端发送此类数据类型的数据(主要是过程 PL/SQLs 的参数)。如需更多信息,您可能需要阅读有关所选数据库的集合、记录和类型支持的内容。

根据您的需要,您只需编写一个 SQL,其中 List 中的每个元素都成为 IN 子句的一部分

例如:select * from user where name in ('Hans', 'Joe', 'Jane');

    //Your below code snippet, 
    ArrayList<String> anrs = new ArrayList<>(); 
    // may be generated elsewhere as
    // List<String> anrs = Arrays.asList("Hans", "Joe", "Jane");
    // can be flattened to comma separated, quoted String
    String inClause = anrs.stream().map(s -> "'"+s+"'")
                      .collect(Collectors.joining(","));       
    System.out.println("List<String> flattened for IN Clause -> "+inClause);
    // which you will use to create SQL
    String selectSQL = String.format("SELECT * FROM rekopf INNER JOIN repos "
        + "ON rekopf.rekopfnum=repos.Reposnum WHERE repos.reposart IN (%s)", 
        inClause);
    java.sql.PreparedStatement pstatement = 
                            connection.prepareStatement(selectSQL);
    java.sql.ResultSet resultSet = pstatement.executeQuery();

    while(resultSet.next()){
        //TODO - process the result
    }

使用 In 子句将 SQL 的参数绑定到 PreparedStatement 并不简单。我将此作为练习留给你,以防你想要超越。