如果一个sql语句包含单行注释,同时在单行注释下面跟着多行注释的情况下,SQLUtils.parseStatements方法返回的SQLStatement列表对象中,注释部分格式异常,导致后续sql执行部分报错,如下图所示
执行结果:
图中多行注释首跑到了单行注释后面,导致多行注释后面的部分无法被识别为注释,从而执行这个sql的时候就会报错。
请问这个问题应该如何解决?
手动去除注释
SQLUtils.parseStatements
方法之前,可以使用字符串处理方法先将注释去除。/\\*.*?\\*/
正则表达式,对于单行注释,可以使用--.*
正则表达式。public class SQLCommentRemover {
public static String removeComments(String sql) {
// 去除多行注释
Pattern multiLineCommentPattern = Pattern.compile("/\\*.*?\\*/", Pattern.DOTALL);
Matcher multiLineMatcher = multiLineCommentPattern.matcher(sql);
sql = multiLineMatcher.replaceAll("");
// 去除单行注释
Pattern singleLineCommentPattern = Pattern.compile("--.*");
Matcher singleLineMatcher = singleLineCommentPattern.matcher(sql);
return singleLineMatcher.replaceAll("");
}
}
- 然后在调用`SQLUtils.parseStatements`之前,先调用`removeComments`方法处理SQL语句:
```java
String sql = "select * from mytable -- 这是单行注释\n" +
"/**这是多行注释\n" +
"这是多行注释第二行*/\n" +
";;;";
sql = SQLCommentRemover.removeComments(sql);
List<SQLStatement> smList = SQLUtils.parseStatements(sql, dbType: "hive");
使用第三方库
JSqlParser
。它可以解析SQL语句,并在解析过程中处理注释。JSqlParser
依赖:<dependency>
<groupId>com.github.jsqlparser</groupId>
<artifactId>jsqlparser</artifactId>
<version>3.2</version>
</dependency>
JSqlParser
处理SQL语句:public class SQLParserExample {
public static void main(String[] args) {
String sql = "select * from mytable -- 这是单行注释\n" +
"/**这是多行注释\n" +
"这是多行注释第二行*/\n" +
";;;";
try {
Statement statement = CCJSqlParserUtil.parse(sql);
// 这里可以进一步处理解析后的Statement对象
} catch (JSQLParserException e) {
e.printStackTrace();
}
}
}
```
SQLUtils.parseStatements
方法SQLUtils.parseStatements
方法是自己编写的,可以修改其内部的解析逻辑,使其能够正确处理这种包含单行注释和多行注释混合的情况。*/
结束符。List<SQLStatement> parseStatements(String sql, String dbType) {
List<SQLStatement> statements = new ArrayList<>();
int index = 0;
while (index < sql.length()) {
// 处理单行注释
if (sql.startsWith("--", index)) {
int endIndex = sql.indexOf('\n', index);
if (endIndex == -1) {
endIndex = sql.length();
}
index = endIndex;
}
// 处理多行注释
else if (sql.startsWith("/*", index)) {
int endIndex = sql.indexOf("*/", index);
if (endIndex == -1) {
throw new IllegalArgumentException("Unclosed multi - line comment");
}
index = endIndex + 2;
}
// 寻找下一个SQL语句
else {
int nextStatementIndex = findNextStatement(sql, index);
String statementStr = sql.substring(index, nextStatementIndex);
SQLStatement statement = parseSingleStatement(statementStr, dbType);
statements.add(statement);
index = nextStatementIndex;
}
}
return statements;
}
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。