最近发现一款很有意思的工具,名字叫GSP(全称General SQL Parser)。他是一款专业的SQL引擎,适用于各种数据库。
以下是他的官方网站:
http://www.sqlparser.com/
我们可以用它来做很多事情,比如解析、格式化SQL等等。是不是很强大呢?我们马上用几个小例子来试验一下吧!
首先这个工具是商业收费的,而且价格不菲。但是他提供了90天的实验版本供大家下载试用。
Java版本的下载地址:
http://www.sqlparser.com/dlaction.php?fid=gspjava&ftitle=General%20SQL%20Parser%20Java%20version
下载解压后,demos是一些实例,javadoc是Java帮助文档,还有UserGuide帮助手册,最重要的gsp.jar就是我们要build path到工程中的jar包了。
下面我们写几个实例
我们先讲讲下面的代码做了哪些事:
1. 定义一个简单的create语句(我们故意把name1的类型错误的设置成varchar2)
2. 创建一个MySQL解析器实例
3. 将sql语句传递给解析器
4. 解析器开始检查语法
5. 判断检查结果,0表示语法正确,1表示语法有错误,并获取返回的错误信息
检查语法的代码如下:
@Test
public void testCheckSyntax(){
String sql = "create table emp1(id1 int,name1 varchar2(200),\n"
+ " money1 double(10,2),\n"
+ " PRIMARY KEY ( id1 ));";
TGSqlParser mysqlSqlParser = new TGSqlParser(EDbVendor.dbvmysql);
mysqlSqlParser.sqltext = sql;
int rs = mysqlSqlParser.checkSyntax();
if(rs == 0){
System.out.println("语法正确!");
}else{
System.out.println("语法错误:"+mysqlSqlParser.getErrormessage());
}
}
我们再看看控制台打印结果:
语法错误:syntax error(10102) near: ((1,41)
no_root_node(-1000) near: no root node(0,0)
正如我们所料,提示语法错误,错误的位置在第一行的41个字符,也就是我们的varchar2。
通常我们编写的SQL语句有一些杂乱,虽然自己不觉得。在Navicat中我们可以很方便的用快捷键format,得到美观、便于阅读的SQL。用General SQL Parser,我们同样可以很容易做到。
我们先讲讲下面的代码做了哪些事:
1. 前三步和“检查语法”是一样的
2. 然后调用解析方法,注意是parse()方法
3. 实例化格式化工具类
4. 用格式化工具工厂类格式化SQL,获取结果
格式化SQL的代码如下:
@Test
public void testFormat(){
String sql = "insert into emp(empno,empnm,deptnm,sal) select empno, empnm, dptnm, sal from emp where empno=:empno;\n" +
"\n" +
"select empno, empnm from (select empno, empnm from emp)";
TGSqlParser sqlParser = new TGSqlParser(EDbVendor.dbvmysql);
sqlParser.sqltext = sql;
sqlParser.parse();
GFmtOpt option = GFmtOptFactory.newInstance();
String formatSQL = FormatterFactory.pp(sqlParser, option);
System.out.println("格式化后的SQL:\n"+formatSQL);
}
我们再看看控制台的结果:
好吧,虽然比想象中的难看点,但至少做到了该换的行都换了,不该换的也换了。
通常我们一个sql文件中,不单单只有一条sql语句,并且一般会有很多注释,那我们怎么提取出每一条SQL语句呢?直接split(“;”),注释怎么处理呢?
用General SQL Parser,我们很简单便捷的做到。
我们看看我们需要做哪些:
1. 前三步还是和前面一样
2. 从解析器中获取statements
3. 遍历statements
4. 获取的TCustomSqlStatement就是每条sql实例
代码如下:
@Test
public void testStatement(){
String sql = " -- 多条SQL语句; "
+ "alter table tab1 add (author_last_published2 date); -- 添加字段\n"//添加1个字段
+ " alter table tab2 add (author_last_published3 date, age number(10,2)); -- 添加两个字段\n"//添加多个字段
+ "drop table tab3; -- 删除表; \n"; //删表;
TGSqlParser sqlParser = new TGSqlParser(EDbVendor.dbvmysql);
sqlParser.sqltext = sql;
sqlParser.parse();
TStatementList stList = sqlParser.sqlstatements;
System.out.println("共有条"+stList.size()+"sql语句!");
for(int i=0; iget(i);
String tsql = customSt.toString();
System.out.println("第"+(i+1)+"条sql:"+tsql);
}
}
结果也是意料之中:
共有条3sql语句!
第1条sql:alter table tab1 add (author_last_published2 date);
第2条sql:alter table tab2 add (author_last_published3 date, age number(10,2));
第3条sql:drop table tab3;
学习demos中实例,更深入全面的了解这个强大的sql工具。
反编译看看这个工具时如何运行的。