错误的 SQL 语法,Oracle:虽然查询在 Spring 引导应用程序的数据库编辑器中运行良好

Bad SQL grammar, Oracle : while the query is working fine in DB editor in Spring Boot Application

我正在使用带有 Spring 启动应用程序的 Oracle 数据库。该查询在 DBeaver 中运行良好,但在实际应用程序中运行不佳。我已经从控制台错误消息中复制了查询。

查询调用函数:

  public List<UserFullNameDesignationDto> getUserFullNameDesignation(String[] userNames) {
    String queryParam = "";
    for (String uName : userNames) {
      queryParam += "'" + uName + "',";
    }
    queryParam = queryParam.substring(0, queryParam.length() - 1);
    String sql =
        "SELECT\n"
            + "\tu.USERNAME,\n"
            + "\tu.FULL_NAME,\n"
            + "\tcd.NAME \n"
            + "FROM\n"
            + "\tUSER_ENTITY u\n"
            + "LEFT JOIN CORE_DESIGNATIONS cd ON u.DESIGNATION_ID = cd.ID \n"
            + "WHERE\n"
            + "\tu.USERNAME IN ("
            + queryParam
            + ");\n";

    var rowMapper = BeanPropertyRowMapper.newInstance(UserFullNameDesignationDto.class);
     List<UserFullNameDesignationDto> list = jdbcTemplate.query(sql, rowMapper);
    System.out.println(list);
    return jdbcTemplate.query(sql, rowMapper);
  }

堆栈跟踪:

org.springframework.jdbc.BadSqlGrammarException: StatementCallback; bad SQL grammar [SELECT
    u.USERNAME,
    u.FULL_NAME,
    cd.NAME 
FROM
    USER_ENTITY u
LEFT JOIN CORE_DESIGNATIONS cd ON u.DESIGNATION_ID = cd.ID 
WHERE
    u.USERNAME IN ('aro_user','afo_user1','afo_user1','afo_user1','afo_user1','afo_user1');
]; nested exception is java.sql.SQLSyntaxErrorException: ORA-00933: SQL command not properly ended
............
Caused by: java.sql.SQLSyntaxErrorException: ORA-00933: SQL command not properly ended

这一行将是

'aro_user','afo_user1','afo_user1','afo_user1','afo_user1','afo_user1'

由变量替换。

据我所知,您必须将存储在该变量中的值拆分成行。如何?像这样:

SQL> with test(queryParam) as
  2  (select q'['aro_user','afo_user1','afo_user1','afo_user1','afo_user1','afo_user1']' from dual)
  3  select regexp_substr(queryParam, '[^,]+', 1, level) val
  4  from test
  5  connect by level <= regexp_count(queryParam, ',') + 1
  6  /

VAL
----------------------------------------------------------------------
'aro_user'
'afo_user1'
'afo_user1'
'afo_user1'
'afo_user1'
'afo_user1'

6 rows selected.

SQL>

意思就是这个:

        + "\tu.USERNAME IN ("
        + queryParam
        + ");\n";

应修改为 queryParam 替换为

(    SELECT REGEXP_SUBSTR (queryParam,
                                 '[^,]+',
                                 1,
                                 LEVEL) val
             FROM test
       CONNECT BY LEVEL <= REGEXP_COUNT (queryParam, ',') + 1)
List<String> userIds = Arrays.asList("User1", "User2");

String inSql = String.join(",", Collections.nCopies(userIds.size(), "?"));

 
List<User> employees = jdbcTemplate.query(String.format("SELECT * FROM Users WHERE id IN (%s)", inSql), userIds.toArray());

请参阅https://www.baeldung.com/spring-jdbctemplate-in-list

错误的根本原因是您在JDBC模板语句中复制了分号(适用于SQL IDE但不在 JDBC)

+ ");\n";

删除它

+ ")\n";

它会起作用(或者你会遇到其他错误;)

无论如何,您应该重新考虑在 SQL 语句中连接输入的方式,以便使用绑定变量。本站有很多绑定IN列表的例子。