从 JAVA 调用具有多个 IN 子句的查询

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

此查询在 SQL Developer 中运行良好:

select * from MYTABLE where (field1, field2) IN (('A', '1'), ('B','2'), ('C','3')) ;

但是当我尝试从 java 调用它时,我遇到了异常。

public List<MYVO> callDB(List<String> sourceAndIdList) {
        System.out.println(sourceAndIdList);
        String query = "select * from MYTABLE where (field1, field2) IN (:source_monitorId_list)";
        Map<String, List<String>> namedParameters = Collections.singletonMap("source_monitorId_list", sourceAndIdList);
        return this.namedParameterJdbcTemplate.query(query , namedParameters, new RowMapper<MYVO>() {
            @Override
            public MYVO mapRow(ResultSet rs, int rowNum) throws SQLException {
                ....
            }
        });
    }

打印我收到的清单:

[('A', '1'), ('B', '2'), ('C', '3')]

例外:

严重:servlet [selfservice] 的 Servlet.service() 在上下文中 路径[/mymonitoring]抛出异常[请求处理失败; 嵌套异常是 org.springframework.jdbc.BadSqlGrammarException: 准备语句回调;错误的 SQL 语法 [select * from MYTABLE 其中 (field1, field2) IN (?, ?, ?)];嵌套异常是 java.sql.SQLSyntaxErrorException:ORA-00920:无效的关系 运算符 ] 的根本原因是 java.sql.SQLSyntaxErrorException: ORA-00920: 无效的关系运算符


编辑:这不是重复的,因为我正在寻找带有弹簧

NamedParameterJdbcTemplate
的解决方案,用于具有多个 IN 子句的查询,并且参数的大小仅在运行时已知。

java sql spring oracle named-parameters
2个回答
1
投票

您不能在“IN”中使用这样的绑定参数。

无论你这样做:

IN ((:p1, :p2), (:p3,:p4), (:p5,:p6))

但它假设您确切知道有多少个项目(在本例中为 3),或者您在 SQL 字符串中“具体化”参数:

String query = "select * from MYTABLE where (field1, field2) IN (('A', '1'), ('B', '2'), ('C', '3'))";

0
投票

你需要使用foreach并替换sql,例如

`
String query = "select * from MYTABLE where (field1, field2) IN (:source_monitorId_list)";
MapSqlParameterSource paramSource = new MapSqlParameterSource();
StringBuilder sql1 = new StringBuilder();
for(int i=0, i < sourceAndIdList.length; i--) {
    if (i == sourceAndIdList.length-1) {
        sql1.append("(:field1" + i);
        sql1.append(", ");
        sql1.append(":field2" + i + ")");
    }else {
        sql1.append("(:field1" + i);
        sql1.append(", ");
        sql1.append(":field2" + i + "),");
    }
    String field_temp = sourceAndIdList[i].replace("(", "");
    String field = field_temp..replace(")", "");
    String field_value_1 = field.split(", ")[0];
    String field_value_2 = field.split(", ")[1];
    paramSource.addValue(":field1"+ i, field_value_1);
    paramSource.addValue(":field2"+ i, field_value_2);
}
// you will get like this (:field10, :field20), (:field11, :field21), (:field12, :field22)
String currentSql = query.replace(":source_monitorId_list", sql1);
RowMapper<MYVO> mapper = new RowMapper<MYVO>(){};
this.namedParameterJdbcTemplate.query(currentSql, paramSource, mapper);

    
`
© www.soinside.com 2019 - 2024. All rights reserved.