Замените множественное появление в SQL-выражении, используя jsqlparser
Я использую jsqlparser для анализа строки SQL и замены имен таблиц в строке.
Мой вклад
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, но это дало мне это:
SELECT id, test
FROM test1_suffix
JOIN test2_suffix
ON test1.aa = test2.bb
WHERE test1.conf = \"test\"
LIMIT 10
Я говорю, что это половина работы, но как я могу сделать остальную часть моей работы?
2 ответа
Итак, вот полный (надеюсь) пример, чтобы заменить все вхождения имен таблиц. Проблема в том, что JSqlParser не отличается между псевдонимами и именами таблиц. Должна быть некоторая логика, чтобы пропустить псевдонимы ваших sqls, если вы не хотите их исправлять.
Использование TableNamesFinder не выполняет всю работу, потому что он проходит AST только настолько, насколько это необходимо для поиска имен таблиц и остановок. Вот почему мой пример использует 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());
}
}
Добавьте псевдоним при разборе, который используется вместо имени таблицы.
SELECT *
FROM test a
WHERE a.conf = 'something'
Затем это должно быть изменено на, то есть предложение where может быть таким же
SELECT *
FROM test_suffix a
WHERE a.conf = 'something'