错误的 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());
错误的根本原因是您在JDBC模板语句中复制了分号(适用于SQL IDE但不在 JDBC)
+ ");\n";
删除它
+ ")\n";
它会起作用(或者你会遇到其他错误;)
无论如何,您应该重新考虑在 SQL 语句中连接输入的方式,以便使用绑定变量。本站有很多绑定IN列表的例子。
我正在使用带有 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());
错误的根本原因是您在JDBC模板语句中复制了分号(适用于SQL IDE但不在 JDBC)
+ ");\n";
删除它
+ ")\n";
它会起作用(或者你会遇到其他错误;)
无论如何,您应该重新考虑在 SQL 语句中连接输入的方式,以便使用绑定变量。本站有很多绑定IN列表的例子。