使用GSP动态修改SQL语句

最近发现一款功能非常强大的解析SQL语句的引擎,GSP(全称General SQL Parser)。这是一款专业的SQL引擎,适用于市面上流行的各种数据库,同时他也支持了马哈鱼分析器对SQL的分析。这是他的官网:

https://www.sqlparser.com/

我们可以使用他对SQL的语法解析,格式化,提取关键字属性,获取数据库metadata等,下面用一些case来介绍下GSP的其中一个功能。

下载

首先去他的官网下载试用版本:

https://sqlparser.com/download.php

下载解压后,src是一些实例,javadoc是Java帮助文档,还有UserGuide帮助手册,external_lib下是gsp所依赖的一些包,最重要的lib下的gsp.jar就是我们要build path到工程中的sdk。

使用GSP动态修改SQL语句_第1张图片

动态修改sql语句

修改简单sql

有下面这样一个SQL

select yb_stage.widetabletest2  
from info_yb_stage yb_stage
where pk_id = 206041839059439594
and yb_stage.r9 = 1000

如果我想要动态修改where条件中的r9的值,只能通过正则的方式获取到r9的值再替换,写起来很麻烦并且不易维护,但使用GSP来完成这个工作就很轻松了,如下:

public void testModifySQL() {
        String sql = "select yb_stage.widetabletest2  \n" +
                "from info_yb_stage yb_stage\n" +
                "where pk_id = 206041839059439594\n" +
                "and yb_stage.r9 = 1000";

        TGSqlParser parser = new TGSqlParser(EDbVendor.dbvpostgresql);
        parser.sqltext = sql;

        int ret = parser.parse();
        if (ret != 0) {
            System.err.println("Error parsing:" + parser.getErrormessage());
          	return;
        }

        TSelectSqlStatement statement = (TSelectSqlStatement) parser.getSqlstatements().get(0);
        TExpression rightOperand = statement.getWhereClause().getCondition().getRightOperand();
        //update value
        rightOperand.getRightOperand().setString("2000");
        System.out.println(statement.toString());
    }

只需要上面几行代码即可完成修改。

其中 parser.parse()是关键,GSP会对整个SQL进行解析同时分析语法的正确性,返回一个结果,如果不为0则表示有语法错误返回错误信息。
整个select语句被解析成TSelectSqlStatement对象,其中where条件是TSelectSqlStatement对象中的WhereClause,其中的条件通过getCondition()方法拿到,yb_stage.r9 = 1000条件在左边通过getRightOperand()方法获取,再getRightOperand()获取最终要修改的1000 ,通过setString方法修改,这样整个SQL就完成了修改,这样整个解析修改过程都很清晰明了,并且可维护。

修改存储过程的sql

上面是一个比较简单的case,下面介绍修改存储工程中sql:

create or replace procedure yb_stage.transfer()
language plpgsql  
as $$
begin
  update yb_stage.widetabletest2  
  set r9 = 1000
  where pk_id = 206041839059439594;
end;
$$

上面这个是postgresql数据库的一个存储过程,对其中r9赋的值1000进行修改:

public void testModifyBody() {
        String sql = "create or replace procedure yb_stage.transfer()\n" +
                "language plpgsql  \n" +
                "as $$\n" +
                "begin\n" +
                "  update yb_stage.widetabletest2  \n" +
                "  set r9 = 1000\n" +
                "  where pk_id = 206041839059439594;\n" +
                "end;\n" +
                "$$";

        TGSqlParser parser = new TGSqlParser(EDbVendor.dbvpostgresql);
        parser.sqltext = sql;

        int ret = parser.parse();
        if (ret != 0) {
            System.err.println("Error parsing:" + parser.getErrormessage());
        }

        TCustomSqlStatement tCustomSqlStatement = parser.getSqlstatements().get(0);
        TCreateProcedureStmt stmt = (TCreateProcedureStmt) tCustomSqlStatement;
        TStatementList bodyStatements = stmt.getBodyStatements();
        TUpdateSqlStatement statement = (TUpdateSqlStatement) bodyStatements.get(0);
        TResultColumn resultColumn = statement.getResultColumnList().getResultColumn(0);
        TExpression expr = resultColumn.getExpr();
        String oldBody = statement.toString();

        //update value
        expr.getRightOperand().setString("2000");

        //Replace sqltext in ${sqltext}$
        String newSql = tCustomSqlStatement.toString().replace(oldBody, statement.toString());
        System.out.println(newSql);
    }

首先一样的通过 parser.parse()解析SQL,SQL被解析成TCreateProcedureStmt对象,从TCreateProcedureStmt对象中拿到TStatementList获取其中的TUpdateSqlStatement对象,这个就是整个存储过程中被解析出来的body数据,即:

update yb_stage.widetabletest2  
  set r9 = 1000
  where pk_id = 206041839059439594;

接下来就是对r9的值修改,首先获取r9的值,通过getResultColumnList()拿到结果集,getRightOperand()找到具体的r9,再通过setString方法修改。

因为这个存储过程中有$$符号,GSP无法像对简单SQL的处理一样对存储过程整体SQL修改,所以具体替换其中被修改后的body,如下:

//Replace sqltext in ${sqltext}$
String newSql = tCustomSqlStatement.toString().replace(oldBody, statement.toString());

这样就完成了修改。

以上就是对GSP对SQL动态修改的介绍,关于GSP的等多功能,请参考下面链接:

参考

GSP官网: https://www.sqlparser.com/

GSP文档:http://support.sqlparser.com/

版权归属古都香港科技有限公司

你可能感兴趣的:(SQLFlow,sql,数据库,mysql)