gpt4 book ai didi

java - 如何在SQL查询中找到条件并用Java替换它1=1

转载 作者:行者123 更新时间:2023-12-02 11:13:13 24 4
gpt4 key购买 nike

我有一个带有条件的 SQL 查询(在 where 子句、having 子句或 join 中)。我需要找到包含带有括号的值的条件,如下所示:{some name} 并用 java 将该条件替换为 1=1(在某些情况下)。

例如

Select *
From customer c inner join address a on c.id = a.customer_id
where c.id > {var1} AND (c.name LIKE {var2} OR a.city = {var3}) AND ... (there could be written all posible operaters and conditions which are allowed by sql)

if var1 = 2, var2 = *ALL, var3 = 'aa' then query should looks like

Select *
From customer c inner join address a on c.id = a.customer_id
where c.id > 2 AND (1=1 OR a.city = 'aa')

我想用 AND|OR 分割 where 条件,然后检查它是否包含 {var2} 然后替换为 1=1,但这不起作用。 (在上面描述的示例中,拆分后它将是(c.name LIKE {var2} 所以(也将被替换)。

有人遇到过这种情况吗以及如何解决的。是否有任何开源库可以查找和替换或者我如何使用正则表达式来做到这一点?

最佳答案

首先,我假设您无法能够动态构建您的sql。为此,您可以采用简单的方法,并可以使用字符串连接来构建 sql,例如

"select ... where c.id > " + myvalue + " ... "

如果你能保证你的表达式只会找到你的sql的特定部分而不是更多,那么对sql使用正则表达式是可行的。这听起来有点微不足道,但对于特定的 sql 来说很难实现,例如:

select '{var2}' from mytable

这里是否应该替换{var2}?我认为不是,因为它是字符串文字的一部分,而不是 where 语句的一部分。

因此,您需要更结构化地查看由 sql 解析器提供的 sql。

使用例如JSqlParser ( https://github.com/JSQLParser/JSqlParser ) 您将能够识别 where 语句的各个部分,并以受控的方式替换 SQL 的各个部分。

但是要进行此解析,您必须将 {val}<​​/strong> 替换为符合 SQL 的内容,例如__val__

因此,您可以使用以下代码来实现替换。它假设替换仅在正确的表达式内完成,但您可以轻松更改它。

String sqlTxt = "Select * from customer c inner join address a on c.id = a.customer_id where c.id > {var1} AND (c.name LIKE {var2} OR  a.city = {var3})";

//replace macro constructs
String sql = sqlTxt.replace("{", "__").replace("}", "__");

//build replacement data
Map<String, String> data = new HashMap<>();
data.put("__var1__", "2");
data.put("__var2__", "*ALL");
data.put("__var3__", "'aa'");

//parse sql
Select select = (Select) CCJSqlParserUtil.parse(sql);

StringBuilder b = new StringBuilder(sql);

//rewrite sql to fit your needs
((PlainSelect) select.getSelectBody()).getWhere().accept(new ExpressionVisitorAdapter() {
int delta = 0; //to correct the position due to former replacements

@Override
protected void visitBinaryExpression(BinaryExpression expr) {
if (expr instanceof ASTNodeAccess) {
if (expr.getRightExpression() instanceof Column) {
Column c = ((Column) expr.getRightExpression());

if (data.containsKey(c.getColumnName())) {
if ("__var2__".equals(c.getColumnName())) {
delta = replaceASTNodeWith(b, delta, (ASTNodeAccess) expr, "1=1");
} else {
delta = replaceASTNodeWith(b, delta, (ASTNodeAccess) expr,
expr.getLeftExpression() + expr.getStringExpression() + data.get(c.getColumnName()));
}
}
}
}
super.visitBinaryExpression(expr);
}
});

System.out.println("parsed sql = " + select.toString());
System.out.println("changed sql = " + b.toString());

由于先前替换的位置发生了变化,因此您的 sql 中的替换有些棘手。

//do the text replacement within the sql
private static int replaceASTNodeWith(StringBuilder sql, int delta, ASTNodeAccess node, String expr) {
sql.replace(
node.getASTNode().jjtGetFirstToken().absoluteBegin + delta - 1,
node.getASTNode().jjtGetLastToken().absoluteEnd + delta - 1,
expr);
return delta + expr.length()
- (node.getASTNode().jjtGetLastToken().absoluteEnd - node.getASTNode().jjtGetFirstToken().absoluteBegin);
}

关于java - 如何在SQL查询中找到条件并用Java替换它1=1,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50463119/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com