如何使用 JSqlParser 添加新条件?
How to add new condition with JSqlParser?
我想为我的 sql 添加新条件。例如,如果查询是;
SELECT EMP_ID, FIRST_NAME FROM EMPLOYEES;
我可以用这个代码添加新的原因;
@Override
protected void setLimit(final PlainSelect ps,final long rowLimit) {
Expression where = ps.getWhere();
if(where == null) {
try {
where = CCJSqlParserUtil.parseCondExpression("ROWNUM < " + (rowLimit+1) );
} catch (JSQLParserException e) {
e.printStackTrace();
}
}
ps.setWhere(where);
}
此代码将查询更改为
SELECT EMP_ID, FIRST_NAME FROM EMPLOYEES WHERE ROWNUM < 10;
...
但问题是当查询像;
SELECT EMP_ID, FIRST_NAME FROM EMPLOYEES WHERE EMP_ID = 10 AND EMP_ID = 10 AND FIRST_NAME = 'Steven';
我无法在当前条件下添加新条件。有没有办法将此查询更改为喜欢;
SELECT EMP_ID, FIRST_NAME FROM EMPLOYEES WHERE EMP_ID = 10 AND EMP_ID = 10 AND FIRST_NAME = 'Steven' AND ROWNUM < 10;
有没有办法用 JSqlParser 做到这一点?
所以这里有两种可能的解决方案(这次比我之前的评论多一点:)):
var sql = "SELECT EMP_ID, FIRST_NAME FROM EMPLOYEES WHERE EMP_ID = 10 AND EMP_ID = 10 AND FIRST_NAME = 'Steven'";
var select = (Select) CCJSqlParserUtil.parse(sql);
var plainselect = (PlainSelect) select.getSelectBody();
//1. add another condition by deparsing the old one and integrate it into
//a new expression, which is parsed and then set into your statement.
var where = CCJSqlParserUtil.parseCondExpression(plainselect.getWhere()
+ " and ROWNUM < 10");
//2. second is building a new AndExpression and sets the left item to the
//original where condition and adds a new condition as the right item.
var where2 = new AndExpression(plainselect.getWhere(),
CCJSqlParserUtil.parseCondExpression("ROWNUM < 10"));
//output both versions. in fact they should and are identical.
plainselect.setWhere(where);
System.out.println(select.toString());
plainselect.setWhere(where2);
System.out.println(select.toString());
此代码两次输出以下内容:
SELECT EMP_ID, FIRST_NAME FROM EMPLOYEES WHERE EMP_ID = 10 AND EMP_ID = 10 AND FIRST_NAME = 'Steven' AND ROWNUM < 10
这是一个 Java >=V10 代码。但是,稍作调整,它也可以使用 JDK 8 运行。
此变体只是将实际的 where 语句转换为字符串,然后用它构建您想要的条件。然后使用 JSqlParser (CCJSqlParserUtil.parseCondExpression) 解析生成的字符串表达式,并将生成的表达式设置到解析后的纯 select 语句 (plainselect.setWhere)
第二个变体使用已解析的对象并围绕它构建一个 AndExpression。要添加的表达式也被构造或再次使用 CCJSqlParserUtil.parseCondExpression 解析并添加到构造的 AndExpression 中。
重要的是要知道,这会构造某种 JSqlParser 对象树项,并且不会一对一映射到 SQL 的实际语义。为此,您应该使用括号来确保这一点,再次使用类型 1 或 2。顺便说一句,括号是使用 Parenthesis 对象构造的。
因此,使用此技术,您可以对 JSqlParsers 对象树进行各种更改。
我想为我的 sql 添加新条件。例如,如果查询是;
SELECT EMP_ID, FIRST_NAME FROM EMPLOYEES;
我可以用这个代码添加新的原因;
@Override
protected void setLimit(final PlainSelect ps,final long rowLimit) {
Expression where = ps.getWhere();
if(where == null) {
try {
where = CCJSqlParserUtil.parseCondExpression("ROWNUM < " + (rowLimit+1) );
} catch (JSQLParserException e) {
e.printStackTrace();
}
}
ps.setWhere(where);
}
此代码将查询更改为
SELECT EMP_ID, FIRST_NAME FROM EMPLOYEES WHERE ROWNUM < 10;
...
但问题是当查询像;
SELECT EMP_ID, FIRST_NAME FROM EMPLOYEES WHERE EMP_ID = 10 AND EMP_ID = 10 AND FIRST_NAME = 'Steven';
我无法在当前条件下添加新条件。有没有办法将此查询更改为喜欢;
SELECT EMP_ID, FIRST_NAME FROM EMPLOYEES WHERE EMP_ID = 10 AND EMP_ID = 10 AND FIRST_NAME = 'Steven' AND ROWNUM < 10;
有没有办法用 JSqlParser 做到这一点?
所以这里有两种可能的解决方案(这次比我之前的评论多一点:)):
var sql = "SELECT EMP_ID, FIRST_NAME FROM EMPLOYEES WHERE EMP_ID = 10 AND EMP_ID = 10 AND FIRST_NAME = 'Steven'";
var select = (Select) CCJSqlParserUtil.parse(sql);
var plainselect = (PlainSelect) select.getSelectBody();
//1. add another condition by deparsing the old one and integrate it into
//a new expression, which is parsed and then set into your statement.
var where = CCJSqlParserUtil.parseCondExpression(plainselect.getWhere()
+ " and ROWNUM < 10");
//2. second is building a new AndExpression and sets the left item to the
//original where condition and adds a new condition as the right item.
var where2 = new AndExpression(plainselect.getWhere(),
CCJSqlParserUtil.parseCondExpression("ROWNUM < 10"));
//output both versions. in fact they should and are identical.
plainselect.setWhere(where);
System.out.println(select.toString());
plainselect.setWhere(where2);
System.out.println(select.toString());
此代码两次输出以下内容:
SELECT EMP_ID, FIRST_NAME FROM EMPLOYEES WHERE EMP_ID = 10 AND EMP_ID = 10 AND FIRST_NAME = 'Steven' AND ROWNUM < 10
这是一个 Java >=V10 代码。但是,稍作调整,它也可以使用 JDK 8 运行。
此变体只是将实际的 where 语句转换为字符串,然后用它构建您想要的条件。然后使用 JSqlParser (CCJSqlParserUtil.parseCondExpression) 解析生成的字符串表达式,并将生成的表达式设置到解析后的纯 select 语句 (plainselect.setWhere)
第二个变体使用已解析的对象并围绕它构建一个 AndExpression。要添加的表达式也被构造或再次使用 CCJSqlParserUtil.parseCondExpression 解析并添加到构造的 AndExpression 中。
重要的是要知道,这会构造某种 JSqlParser 对象树项,并且不会一对一映射到 SQL 的实际语义。为此,您应该使用括号来确保这一点,再次使用类型 1 或 2。顺便说一句,括号是使用 Parenthesis 对象构造的。
因此,使用此技术,您可以对 JSqlParsers 对象树进行各种更改。