使用 jsqlparser 替换 sql 语句中的多次出现
Replace multi appearance in sql statement using jsqlparser
我正在使用 jsqlparser 解析 SQL 字符串并替换字符串中的 table 名称。
我的输入是
SELECT id, test
FROM test1 JOIN test2
ON test1.aa = test2.bb
WHERE test1.conf = \"test\"
LIMIT 10"
我的目标输出是
SELECT id, test
FROM test1_suffix
JOIN test2_suffix
ON test1_suffix.aa = test2_suffix.bb
WHERE test1_suffix.conf = \"test\"
LIMIT 10"
我设法通过扩展 TablesNamesFinder 来替换 table 名称,但它给了我这个:
SELECT id, test
FROM test1_suffix
JOIN test2_suffix
ON test1.aa = test2.bb
WHERE test1.conf = \"test\"
LIMIT 10
我说这已经完成了一半的工作,但我怎样才能完成剩下的工作呢?
在解析时添加一个别名而不是 table 名称。
SELECT *
FROM test a
WHERE a.conf = 'something'
那么这个应该改成,就是where子句可以一样
SELECT *
FROM test_suffix a
WHERE a.conf = 'something'
所以这是一个完整的(希望如此)示例,用于替换 table 名称的所有出现。问题是,JSqlParser 在别名和 table 名称之间没有区别。如果您不想更正这些别名,则必须有一些逻辑来跳过您的 sql 的别名。
TableNamesFinder 的使用并没有完成全部工作,因为它只遍历 AST 直到需要查找 table 名称并在那时停止。这就是为什么我的示例使用 deparsers.
此代码转换
select id, test from test where name = "test"
到
SELECT id, test FROM test_mytest WHERE name = "test"
和
select * from t2 join t1 on t1.aa = t2.bb where t1.a = "someCondition" limit 10
到
SELECT * FROM t2_mytest JOIN t1_mytest ON t1_mytest.aa = t2_mytest.bb WHERE t1_mytest.a = "someCondition" LIMIT 10
我认为这可以解决您的问题。
public class SimpleSqlParser24 {
public static void main(String args[]) throws JSQLParserException {
replaceTableName("select id, test from test where name = \"test\"");
replaceTableName("select * from t2 join t1 on t1.aa = t2.bb where t1.a = \"someCondition\" limit 10");
}
private static void replaceTableName(String sql) throws JSQLParserException {
Select select = (Select) CCJSqlParserUtil.parse(sql);
StringBuilder buffer = new StringBuilder();
ExpressionDeParser expressionDeParser = new ExpressionDeParser() {
@Override
public void visit(Column tableColumn) {
if (tableColumn.getTable() != null) {
tableColumn.getTable().setName(tableColumn.getTable().getName() + "_mytest");
}
super.visit(tableColumn);
}
};
SelectDeParser deparser = new SelectDeParser(expressionDeParser, buffer) {
@Override
public void visit(Table tableName) {
tableName.setName(tableName.getName() + "_mytest");
super.visit(tableName);
}
};
expressionDeParser.setSelectVisitor(deparser);
expressionDeParser.setBuffer(buffer);
select.getSelectBody().accept(deparser);
System.out.println(buffer.toString());
}
}
我正在使用 jsqlparser 解析 SQL 字符串并替换字符串中的 table 名称。
我的输入是
SELECT id, test
FROM test1 JOIN test2
ON test1.aa = test2.bb
WHERE test1.conf = \"test\"
LIMIT 10"
我的目标输出是
SELECT id, test
FROM test1_suffix
JOIN test2_suffix
ON test1_suffix.aa = test2_suffix.bb
WHERE test1_suffix.conf = \"test\"
LIMIT 10"
我设法通过扩展 TablesNamesFinder 来替换 table 名称,但它给了我这个:
SELECT id, test
FROM test1_suffix
JOIN test2_suffix
ON test1.aa = test2.bb
WHERE test1.conf = \"test\"
LIMIT 10
我说这已经完成了一半的工作,但我怎样才能完成剩下的工作呢?
在解析时添加一个别名而不是 table 名称。
SELECT *
FROM test a
WHERE a.conf = 'something'
那么这个应该改成,就是where子句可以一样
SELECT *
FROM test_suffix a
WHERE a.conf = 'something'
所以这是一个完整的(希望如此)示例,用于替换 table 名称的所有出现。问题是,JSqlParser 在别名和 table 名称之间没有区别。如果您不想更正这些别名,则必须有一些逻辑来跳过您的 sql 的别名。
TableNamesFinder 的使用并没有完成全部工作,因为它只遍历 AST 直到需要查找 table 名称并在那时停止。这就是为什么我的示例使用 deparsers.
此代码转换
select id, test from test where name = "test"
到
SELECT id, test FROM test_mytest WHERE name = "test"
和
select * from t2 join t1 on t1.aa = t2.bb where t1.a = "someCondition" limit 10
到
SELECT * FROM t2_mytest JOIN t1_mytest ON t1_mytest.aa = t2_mytest.bb WHERE t1_mytest.a = "someCondition" LIMIT 10
我认为这可以解决您的问题。
public class SimpleSqlParser24 {
public static void main(String args[]) throws JSQLParserException {
replaceTableName("select id, test from test where name = \"test\"");
replaceTableName("select * from t2 join t1 on t1.aa = t2.bb where t1.a = \"someCondition\" limit 10");
}
private static void replaceTableName(String sql) throws JSQLParserException {
Select select = (Select) CCJSqlParserUtil.parse(sql);
StringBuilder buffer = new StringBuilder();
ExpressionDeParser expressionDeParser = new ExpressionDeParser() {
@Override
public void visit(Column tableColumn) {
if (tableColumn.getTable() != null) {
tableColumn.getTable().setName(tableColumn.getTable().getName() + "_mytest");
}
super.visit(tableColumn);
}
};
SelectDeParser deparser = new SelectDeParser(expressionDeParser, buffer) {
@Override
public void visit(Table tableName) {
tableName.setName(tableName.getName() + "_mytest");
super.visit(tableName);
}
};
expressionDeParser.setSelectVisitor(deparser);
expressionDeParser.setBuffer(buffer);
select.getSelectBody().accept(deparser);
System.out.println(buffer.toString());
}
}