0

我正在使用 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

我说这已经完成了一半的工作,但我怎么能完成剩下的工作呢?

4

2 回答 2

2

所以这是一个完整的(希望是)示例来替换所有出现的表名。问题是,JSqlParser在别名和表名之间没有区别。如果您不想更正这些别名,则必须有一些逻辑来跳过 sql 的别名。

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());
    }
}
于 2018-08-10T08:00:06.837 回答
0

在解析时添加一个别名,而不是表名。

SELECT * 
FROM test a
WHERE a.conf = 'something'

那么这个要改成,也就是where子句可以一样

SELECT * 
FROM test_suffix a
WHERE a.conf = 'something'
于 2018-08-08T09:05:30.690 回答