将 SQL LIKE 子句转换为 JAVA PrepareStatement

问题描述 投票:0回答:1

我在将现有代码转换为 PrepareStatement 时遇到问题,如下面的代码所示。 在这种情况下,我使用 LIKE 子句。我的数据库是 Oracle 19c。

public int getCountReprintHistory(String request_date, String statement_type, String option_type, String cust_no) {
        String sql = "";

    if ( request_date.equals("") && statement_type.equals("") && option_type.equals("") && cust_no.equals("") ) {
            sql += "SELECT COUNT(REPRINTLOG_DATE) FROM TBL_REPRINT_HISTORY2 ";
            sql += "ORDER BY REPRINTLOG_JOBID DESC ";
        } else {                    
            sql += "SELECT COUNT(REPRINTLOG_DATE) FROM TBL_REPRINT_HISTORY2 ";
            sql += "WHERE TO_CHAR(REPRINTLOG_DATE,'dd/mm/yyyy') LIKE '%" + request_date +"%' ";
            sql += "AND REPRINTLOG_STATEMENT_TYPE LIKE '%" + statement_type +"%' ";
            sql += "AND REPRINTLOG_OPTION_TYPE LIKE '%" + option_type +"%' ";
            sql += "AND REPRINTLOG_CUSTOMER_NO LIKE '%" + cust_no +"%' ";
            sql += "ORDER BY REPRINTLOG_JOBID DESC ";
        }       
        return jdbcTemplate.queryForObject(sql, Integer.class);
    }

我试过这个查询,但它返回 ==> SQLErrorCodes loaded: [DB2, Derby, H2, HSQL, Informix, MS-SQL, MySQL, Oracle, PostgreSQL, Sybase, Hana].

        public int getCountReprintHistory(String request_date, String statement_type, String option_type, String cust_no) {
        String sql = "";
        
        if ( request_date.equals("") && statement_type.equals("") && option_type.equals("") && cust_no.equals("") ) {
            sql += "SELECT COUNT(REPRINTLOG_DATE) FROM TBL_REPRINT_HISTORY2 ";
            sql += "ORDER BY REPRINTLOG_JOBID DESC ";
        } else {                    
            sql += "SELECT COUNT(REPRINTLOG_DATE) FROM TBL_REPRINT_HISTORY2 ";
            sql += "WHERE TO_CHAR(REPRINTLOG_DATE,'dd/mm/yyyy') LIKE '%' || ? || '%' ";
            sql += "AND REPRINTLOG_STATEMENT_TYPE LIKE '%' || ? || '%' ";
            sql += "AND REPRINTLOG_OPTION_TYPE LIKE '%' || ? || '%' ";
            sql += "AND REPRINTLOG_CUSTOMER_NO LIKE '%' || ? || '%' ";
            sql += "ORDER BY REPRINTLOG_JOBID DESC ";
        }       
        return jdbcTemplate.queryForObject(sql, new Object[]{request_date,statement_type,option_type,cust_no}, Integer.class);
    }
java prepared-statement sql-like
1个回答
1
投票

尝试这样的事情:

public int getCountReprintHistory(String request_date, String statement_type, String option_type, String cust_no) throws SQLException {
    try (PreparedStatement stmt = cnt.prepareStatement(
                "SELECT COUNT(REPRINTLOG_DATE) FROM TBL_REPRINT_HISTORY2 "
                + "WHERE TO_CHAR(REPRINTLOG_DATE,'dd/mm/yyyy') LIKE '%' || ? || '%' "
                + "AND REPRINTLOG_STATEMENT_TYPE LIKE '%' || ? || '%' "
                + "AND REPRINTLOG_OPTION_TYPE LIKE '%' || ? || '%' "
                + "AND REPRINTLOG_CUSTOMER_NO LIKE '%' || ? || '%' "
                + "ORDER BY REPRINTLOG_JOBID DESC ")) {
        stmt.setString(1, request_date);
        stmt.setString(2, statement_type);
        stmt.setString(3, option_type);
        stmt.setString(4, cust_no);
        try (ResultSet rs = stmt.executeQuery()) {
            rs.next();
            return rs.getInt(1);
        }
    }
}

如果要优化无约束情况:

public int getCountReprintHistory(String request_date, String statement_type, String option_type, String cust_no) throws SQLException {
    PreparedStatement stmt;
    boolean unconstrained = request_date.equals("") && statement_type.equals("") && option_type.equals("") && cust_no.equals("");
    if ( unconstrained ) {
        stmt = cnt.prepareStatement(
                "SELECT COUNT(REPRINTLOG_DATE) FROM TBL_REPRINT_HISTORY2 "
                + "ORDER BY REPRINTLOG_JOBID DESC ");
    } else {                    
        stmt = cnt.prepareStatement(
                "SELECT COUNT(REPRINTLOG_DATE) FROM TBL_REPRINT_HISTORY2 "
                + "WHERE TO_CHAR(REPRINTLOG_DATE,'dd/mm/yyyy') LIKE '%' || ? || '%' "
                + "AND REPRINTLOG_STATEMENT_TYPE LIKE '%' || ? || '%' "
                + "AND REPRINTLOG_OPTION_TYPE LIKE '%' || ? || '%' "
                + "AND REPRINTLOG_CUSTOMER_NO LIKE '%' || ? || '%' "
                + "ORDER BY REPRINTLOG_JOBID DESC ");
    }
    try {
        if (!unconstrained) {
            stmt.setString(1, request_date);
            stmt.setString(2, statement_type);
            stmt.setString(3, option_type);
            stmt.setString(4, cust_no);
        }
        try (ResultSet rs = stmt.executeQuery()) {
            rs.next();
            return rs.getInt(1);
        }
    } finally {
        stmt.close();
    }
}

再优化一点:

public int getCountReprintHistory(String request_date, String statement_type, String option_type, String cust_no) throws SQLException {
    List<String> conds = new ArrayList<>();
    List<String> parms = new ArrayList<>();
    if (!request_date.equals("")) {
        conds.add("TO_CHAR(REPRINTLOG_DATE,'dd/mm/yyyy') LIKE '%' || ? || '%'");
        parms.add(request_date);
    }
    if (!request_date.equals("")) {
        conds.add("REPRINTLOG_STATEMENT_TYPE LIKE '%' || ? || '%'");
        parms.add(statement_type);
    }
    if (!request_date.equals("")) {
        conds.add("REPRINTLOG_OPTION_TYPE LIKE '%' || ? || '%'");
        parms.add(option_type);
    }
    if (!request_date.equals("")) {
        conds.add("REPRINTLOG_CUSTOMER_NO LIKE '%' || ? || '%'");
        parms.add(cust_no);
    }
    StringBuilder buf = new StringBuilder(
            "SELECT COUNT(REPRINTLOG_DATE) FROM TBL_REPRINT_HISTORY2 ");
    if (!conds.isEmpty()) {
        buf.append("WHERE ");
        buf.append(conds.get(0));
        for (int i = 1; i < conds.size(); ++i) {
            buf.append(" AND ");
            buf.append(conds.get(i));
        }
    }
    try (PreparedStatement stmt = cnt.prepareStatement(buf.toString())) {
        for (int i = 0; i < parms.size(); ++i) {
            stmt.setString(i+1, parms.get(i));
        }
        try (ResultSet rs = stmt.executeQuery()) {
            rs.next();
            return rs.getInt(1);
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.