Prepared Statement setString 向 String 添加不必要的单引号

Prepared Statement setString adding unnecessary single quotes to String

背景

我正在尝试将 ArrayList 的内容设置到 Db2 SQL 语句中的 IN 子句中。我正在使用 PreparedStatement 来构建我的查询。 这是我们的编码标准。

我试过#1

我研究了几种实现此目的的方法。我首先尝试使用 setArray(),如这个问题所示:How to use an arraylist as a prepared statement parameter 结果是我得到了 Err com.ibm.db2.jcc.am.SqlFeatureNotSupportedException: [jcc][t4][10344][11773][3.65.110] Data type ARRAY is not supported on the target server. ERRORCODE=-4450, SQLSTATE=0A502 的错误 在这个障碍之后,我继续前进到 #2

我试过的#2

然后我尝试使用 Apache Commons StringUtils 将 ArrayList 转换为逗号分隔的字符串,就像我的 IN 子句所需要的那样。结果是这完全符合我的需要,我有一个字符串,所有结果都用逗号分隔。

问题:

setString() 方法是在我的字符串的开头和结尾添加单引号。我已经用过很多次了,但从来没有这样做过。 有谁知道是否有解决这个问题的方法,或者使用 PreparedStatement 的替代方法? 如果我使用字符串连接,我的查询就可以工作。

代码(上面有解释):

    List<String> selectedStatuses = new ArrayList<String>(); //Used to store contents of scoped var

    //Get Contents of Checkbox which are in the form of a List
    selectedStatuses = (List) viewScope.get("selectedStatuses");

    String selectedStatusesString = StringUtils.join(selectedStatuses, ",");

    .... WHERE ATM_DET_ATM_STAT IN (?)";
    ps.setString(1, selectedStatusesString);

显示字符串正确值的日志值

调试:selectedStatusesString:'OPEN','CLOSED','WOUNDED','IN PROGRESS'

视觉错误结果

开头和结尾的引号有问题。

根据 DB2 Survival Guide,使用两个撇号 '' 在 DB2 上得到一个撇号。然后调用 .setString().

要使 IN 子句起作用,您需要的标记与您的值一样多:

String sql = "SELECT * FROM MyTable WHERE Stat IN (?,?,?,?)";
try (PreparedStatement stmt = conn.prepareStatement(sql)) {
    stmt.setString(1, "OPEN");
    stmt.setString(2, "CLOSED");
    stmt.setString(3, "WOUNDED");
    stmt.setString(4, "IN PROGRESS");
    try (ResultSet rs = stmt.executeQuery()) {
        // use rs here
    }
}

由于您有一个动态的值列表,您需要这样做:

List<String> stats = Arrays.asList("OPEN", "CLOSED", "WOUNDED", "IN PROGRESS");

String markers = StringUtils.repeat(",?", stats.size()).substring(1);
String sql = "SELECT * FROM MyTable WHERE Stat IN (" + markers + ")";
try (PreparedStatement stmt = conn.prepareStatement(sql)) {
    for (int i = 0; i < stats.size(); i++)
        stmt.setString(i + 1, stats.get(i));
    try (ResultSet rs = stmt.executeQuery()) {
        // use rs here
    }
}

从 Java 11 开始,不再需要 StringUtils

String markers = ",?".repeat(stats.size()).substring(1);