使用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。
动态修改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 valuerightOperand.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 $$
beginupdate yb_stage.widetabletest2 set r9 = 1000where 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 valueexpr.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 = 1000where 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/
版权归属古都香港科技有限公司
感兴趣的联系:Zy2133223
使用GSP动态修改SQL语句相关推荐
- linux 软件集成工具箱,在PB中动态修改SQL语句
在PB中动态修改SQL语句 分享到: 江苏省南通电信局网管中心 黄莹 ---- PowerBuilder是图形界面的Client/Server应用程序开发环境,可以很容易开发出功能强大的应用程序,在当 ...
- oracle中执行动态sql语句吗,oracle中有没有可动态执行sql语句的函数
oracle中有没有可动态执行sql语句的函数 关注:233 答案:2 手机版 解决时间 2021-03-05 15:53 提问者祗剩寂寞 2021-03-04 22:38 oracle中有没有可 ...
- mysql带参数的sql_MySql存储过程是带参数的存储过程(动态执行SQL语句)
下文介绍的MySql存储过程是带参数的存储过程(动态执行SQL语句),该MySql存储过程是根据用户输入的条件和排序方式查询用户的信息,排序条件可以没有调用方式: call GetUsersDynam ...
- 捷信达酒店管理系统密码修改SQL语句
捷信达酒店管理系统密码修改SQL语句 密码是加密过的,也不知道加密算法,就这么查询一个已知用户的密码插入进去就好. UPDATE gsOperator SET Pwd = (select Pwd fr ...
- mysql函数 动态语句_自定义函数动态执行SQL语句
Oracle 动态SQL有两种写法:用 DBMS_SQL 或 execute immediate,建议使用后者. DDL 和 DML Sql代码 收藏代码 /*** DDL ***/ begin EX ...
- mysql(十)条件语句、循环语句、动态执行SQL语句
MySQL数据库-条件语句.循环语句.动态执行SQL语句 1.if条件语句 delimiter \\ CREATE PROCEDURE proc_if () BEGINdeclare i int de ...
- excel动态生成Sql语句
文章目录 0. 前言 1. 先说结论 2. 例子 0. 前言 由于工作原因,无意中发现有时候有些数据来由形式是excel文件,需要把里面的值变成sql语句,然后去数据库中执行. 因此记录下如何让exc ...
- Mybatis拦截器修改sql语句
拦截器介绍 MyBatis提供了一种插件(plugin)的功能,虽然叫做插件,但其实这是拦截器功能. MyBatis 允许你在已映射语句执行过程中的某一点进行拦截调用.默认情况下,MyBatis 允许 ...
- 老年人教程:MyBatis拦截器动态修改SQL(更新与插入)语句
注:本文编写与 2019年12月17日, 内容可能存在时效性问题. 数据库使用MySQL5.7 集成于SpringBoot 2.0.X , 引用国产的开源工具类Hutool 本教程建议显示大纲视图 配 ...
最新文章
- 4.Ext JS Ext.data.Store本地过滤
- linux splash qt,ubuntu14.04 splash安装
- Python(11):正则表达式
- 使用注解版AOP解决事务问题
- Spark Master的注册机制与状态管理
- 快手 算法工程师 0825 笔试题
- 使用 dpu 检视 dump 中的字符串.
- “软下来”的苹果和小米能否拯救智能手机的焦虑? | 畅言
- 通用线程 -- sed 实例
- 21.策略模式(Strategy Pattern)
- java web 教程_Java Web服务教程
- android 如何从服务器端的数据库中拿数据,在客户端显示类?
- 阿里架构师的日志:带你快速理解微服务架构;理解微服务架构的核心
- 怎么用计算机求logo,小学计算机教学中的LOGO语言教学(转载)
- 如何免费下载B站视频!!!实测可用!!!
- Matlab 生成方波信号
- 对SPEA算法的一些总结
- 奔驰S400升级主动式氛围灯,大饼轮毂,4D旋转高音
- nyoj 543 遥控器 第五届河南省程序设计大赛
- Google浏览器打开axure产品原型的解决方案