java得到sql语句表名_使用fdb-sql-parser替换SQL语句中的表名
导语
因为项目中要做跨数据源的数据分析功能,所以使用Presto这个开源框架。但是使用Presto的时候需要指定当前表所在的数据库类型和数据库名,所以需要对SQL语句中的表名进行捕获和替换。
一.探索过程
首先使用的是HiveParse这个工具,修改了语法树中的表名,但是好像没有提供由语法树得到SQL语句的方法。之后又使用了Druid的SQL解析器,但是这个框架结构很复杂,看了一天也没弄清处解析的流程。后来看到这篇博客JAVA - Sql解析工具fdb-sql-parser简单使用并得到启发,可以替换查询语句中的表名。
二.编写测试代码
引入pom文件
com.foundationdb
fdb-sql-parser
1.3.0
复写NodeToString这个类
NodeToString这个类的作用就是将语法树转换为SQL语句,遍历到表节点是会调用fromBaseTable(FromBaseTable node):String方法
public class MyNodeToString extends NodeToString{
@Override
protected String fromBaseTable(FromBaseTable node) throws StandardException {
String tn = "数据库类型." + toString(node.getOrigTableName());
String n = node.getCorrelationName();
if (n == null)
return tn;
else
return tn + " AS " + n;
}
}
进行调用
import com.foundationdb.sql.StandardException;
import com.foundationdb.sql.parser.SQLParser;
import com.foundationdb.sql.parser.StatementNode;
import java.util.ArrayList;
import java.util.List;
/**
* @Author chenxl
* @Date 2016/11/16 22:00
* @Describle
*/
public class Parser {
public static void main(String[] args) throws StandardException {
String sql1 = "Select * from zpc1";
String sql2 = "Select name,ip from zpc2 bieming where age > 10 and area in (select area from city)";
String sql3 = "Select d.name,d.ip from (select * from zpc3 where age > 10 and area in (select area from city)) d";
String sql4 = "create table zpc(id string, name string)";
// String sql5 = "insert overwrite table tmp1 PARTITION (partitionkey='2008-08-15') select * from tmp";
// String sql6 = "FROM ( SELECT p.datekey datekey, p.userid userid, c.clienttype FROM detail.usersequence_client c JOIN fact.orderpayment p ON p.orderid = c.orderid "
// + " JOIN default.user du ON du.userid = p.userid WHERE p.datekey = 20131118 ) base INSERT OVERWRITE TABLE `test`.`customer_kpi` SELECT base.datekey, "
// + " base.clienttype, count(distinct base.userid) buyer_count GROUP BY base.datekey, base.clienttype";
// String sql7 = "SELECT id, value FROM (SELECT id, value FROM p1 UNION ALL SELECT 4 AS id, 5 AS value FROM p1 limit 1) u";
String sql8 = "select dd from(select id+1 dd from zpc) d";
String sql9 = "select dd+1 from(select id+1 dd from zpc) d";
// String sql10 = "truncate table zpc";
// String sql11 = "drop table zpc";
String sql12 = "select * from tablename where unix_timestamp(cz_time) > unix_timestamp('2050-12-31 15:32:28')";
String sql15 = "alter table old_table_name RENAME TO new_table_name";
String sql16 = "select statis_date,time_interval,gds_cd,gds_nm,sale_cnt,discount_amt,discount_rate,price,etl_time,pay_amt from o2ostore.tdm_gds_monitor_rt where time_interval = from_unixtime(unix_timestamp(concat(regexp_replace(from_unixtime(unix_timestamp('201506181700', 'yyyyMMddHHmm')+ 84600 , 'yyyy-MM-dd HH:mm'),'-| |:',''),'00'),'yyyyMMddHHmmss'),'yyyy-MM-dd HH:mm:ss')";
// String sql13 = "INSERT OVERWRITE TABLE u_data_new SELECT TRANSFORM (userid, movieid, rating, unixtime) USING 'python weekday_mapper.py' AS (userid, movieid, rating, weekday) FROM u_data";
String sql14 = "SELECT a.* FROM a JOIN b ON (a.id = b.id AND a.department = b.department)";
// String sql17 = "LOAD DATA LOCAL INPATH \"/opt/data/1.txt\" OVERWRITE INTO TABLE table1";
// String sql18 = "CREATE TABLE table1 ( column1 STRING COMMENT 'comment1', column2 INT COMMENT 'comment2' )";
// String sql19 = "ALTER TABLE events RENAME TO 3koobecaf";
// String sql20 = "ALTER TABLE invites ADD COLUMNS (new_col2 INT COMMENT 'a comment')";
// String sql21 = "alter table mp add partition (b='1', c='1')";
// String sql22 = "select login.uid from login day_login left outer join (select uid from regusers where dt='20130101') day_regusers on day_login.uid=day_regusers.uid where day_login.dt='20130101' and day_regusers.uid is null";
String sql23 = "select name from (select * from zpc left outer join def on zpc.id=def.id) d";
List list = new ArrayList();
list.add(sql1);
list.add(sql2);
list.add(sql3);
// list.add(sql4);
// list.add(sql5);
// list.add(sql6);
// list.add(sql7);
list.add(sql8);
list.add(sql9);
// list.add(sql10);
// list.add(sql11);
list.add(sql12);
// list.add(sql13);
list.add(sql14);
list.add(sql15);
list.add(sql16);
// list.add(sql17);
// list.add(sql18);
// list.add(sql19);
// list.add(sql20);
// list.add(sql21);
// list.add(sql22);
list.add(sql23);
SQLParser parser = new SQLParser();
// StatementNode stmt = parser.parseStatement(
// "select userid,username,password " +
// "from sys_user,sys_money where username = 'isea533'");
// stmt.treePrint();
MyNodeToString unparser = new MyNodeToString();
String sql = "";
for (String s : list) {
StatementNode stmt = parser.parseStatement(s);
sql = unparser.toString(stmt);
System.out.println(sql);
}
}
}
测试结果
E:\soft\Java\jdk1.8.0_101\bin\java -Didea.launcher.port=7532 "-Didea.launcher.bin.path=E:\soft\IntelliJ IDEA 2016.2.4\bin" -Dfile.encoding=UTF-8 -classpath "E:\soft\Java\jdk1.8.0_101\jre\lib\charsets.jar;E:\soft\Java\jdk1.8.0_101\jre\lib\deploy.jar;E:\soft\Java\jdk1.8.0_101\jre\lib\ext\access-bridge-64.jar;E:\soft\Java\jdk1.8.0_101\jre\lib\ext\cldrdata.jar;E:\soft\Java\jdk1.8.0_101\jre\lib\ext\dnsns.jar;E:\soft\Java\jdk1.8.0_101\jre\lib\ext\jaccess.jar;E:\soft\Java\jdk1.8.0_101\jre\lib\ext\jfxrt.jar;E:\soft\Java\jdk1.8.0_101\jre\lib\ext\localedata.jar;E:\soft\Java\jdk1.8.0_101\jre\lib\ext\nashorn.jar;E:\soft\Java\jdk1.8.0_101\jre\lib\ext\sunec.jar;E:\soft\Java\jdk1.8.0_101\jre\lib\ext\sunjce_provider.jar;E:\soft\Java\jdk1.8.0_101\jre\lib\ext\sunmscapi.jar;E:\soft\Java\jdk1.8.0_101\jre\lib\ext\sunpkcs11.jar;E:\soft\Java\jdk1.8.0_101\jre\lib\ext\zipfs.jar;E:\soft\Java\jdk1.8.0_101\jre\lib\javaws.jar;E:\soft\Java\jdk1.8.0_101\jre\lib\jce.jar;E:\soft\Java\jdk1.8.0_101\jre\lib\jfr.jar;E:\soft\Java\jdk1.8.0_101\jre\lib\jfxswt.jar;E:\soft\Java\jdk1.8.0_101\jre\lib\jsse.jar;E:\soft\Java\jdk1.8.0_101\jre\lib\management-agent.jar;E:\soft\Java\jdk1.8.0_101\jre\lib\plugin.jar;E:\soft\Java\jdk1.8.0_101\jre\lib\resources.jar;E:\soft\Java\jdk1.8.0_101\jre\lib\rt.jar;E:\IDEAProject\SQLParseTest\target\test-classes;E:\IDEAProject\SQLParseTest\target\classes;C:\Users\chenxl\.m2\repository\com\foundationdb\fdb-sql-parser\1.3.0\fdb-sql-parser-1.3.0.jar;E:\soft\IntelliJ IDEA 2016.2.4\lib\idea_rt.jar" com.intellij.rt.execution.application.AppMain Parser
SELECT * FROM 数据库类型.zpc1
SELECT name, ip FROM 数据库类型.zpc2 AS bieming WHERE (age > 10) AND (area IN (SELECT area FROM 数据库类型.city))
SELECT d.name AS name, d.ip AS ip FROM (SELECT * FROM 数据库类型.zpc3 WHERE (age > 10) AND (area IN (SELECT area FROM 数据库类型.city))) AS d
SELECT dd FROM (SELECT (id + 1) AS dd FROM 数据库类型.zpc) AS d
SELECT (dd + 1) FROM (SELECT (id + 1) AS dd FROM 数据库类型.zpc) AS d
SELECT * FROM 数据库类型.tablename WHERE unix_timestamp(cz_time) > (unix_timestamp(('2050-12-31 15:32:28')))
SELECT a.* FROM 数据库类型.a INNER JOIN 数据库类型.b ON ((a.id = b.id) AND (a.department = b.department))
**UNKNOWN(114)**
SELECT statis_date, time_interval, gds_cd, gds_nm, sale_cnt, discount_amt, discount_rate, price, etl_time, pay_amt FROM 数据库类型.o2ostore.tdm_gds_monitor_rt WHERE time_interval = (from_unixtime((unix_timestamp((concat((regexp_replace((from_unixtime(((unix_timestamp('201506181700', 'yyyyMMddHHmm')) + 84600), ('yyyy-MM-dd HH:mm'))), ('-| |:'), '')), '00')), 'yyyyMMddHHmmss')), ('yyyy-MM-dd HH:mm:ss')))
SELECT name FROM (SELECT * FROM 数据库类型.zpc LEFT OUTER JOIN 数据库类型.def ON (zpc.id = def.id)) AS d
Process finished with exit code 0
上述代码测试了有些查询操作,至于修改和插入还未测试,我们的需求主要是查询。
java得到sql语句表名_使用fdb-sql-parser替换SQL语句中的表名相关推荐
- mysql 批量替换 所有表_[收藏]批量替换一个数据库中所有表中所有记录
/***********批量替换一个数据库中所有表中所有记录************/ declare @delStr nvarchar(500) set @delStr='这里是要替换的字符' /* ...
- sql跨表查询_白话django之ORM的查询语句
教程源码:z991/django_turital 在日常开发中,数据库的增删改查(CDUR)中,查询需求偏多,所以查询的语法比增删改操作多得多,尤其是跨表关联查询,可以让代码精简很多年. 直接上代码吧 ...
- sql活动监视器 死锁_使用system_health扩展事件监视SQL Server死锁
sql活动监视器 死锁 Performance monitoring is a must to do the task for a DBA. You should ensure that the da ...
- sql server jar包_老王,怎么完整SQL的显示日志,而不是???...
点击蓝色"Java面试那些事儿"关注我哟 加个"星标",优质文章,第一时间送达 来源:http://1t.click/ag6q在常规项目的开发中可能最容易出问题 ...
- sql 占比计算_数据库索引的优化及SQL处理过程(建议收藏)
想要设计出好的索引,首先必须了解SQL语句在数据库服务器中的处理过程,本文介绍 数据库索引设计与优化 中几个对索引优化非常重要的概念. 谓词 谓词就是条件表达式. SQL语句的where子句由一个或者 ...
- Java 错误:找不到或无法加载主类(源文件中含有包名 package)
1. 问题定位 编译(javac)和执行(java)java 程序时,出现这种类型的错误:找不到或无法加载主类: 首先排除是否是环境变量配置不当造成的问题,只要保证,命令行界面能够识别 javac/j ...
- mongo 改字段名_一日一技:修改MongoDB集合中的字段名
一日一技:修改MongoDB集合中的字段名 一日一技是一个每天更新的栏目,旨在使用3分钟的时间让你每天都有新的进步. 在我们使用MongoDB的过程中,经常会出现修改数据的情况.我们一般使用 upda ...
- python合法的变量名有哪些_中国大学MOOC: 以下不是Python中合法变量名的是______。...
中国大学MOOC: 以下不是Python中合法变量名的是______. 答:5MyGod "32位微型计算机"中的32指的是( ) 答:机器字长 以下是细胞因子治疗肿瘤的特点的是: ...
- java sql查询空内容_返回null值而不是sql查询中的空集
比方说,有两个表: select * from users; +-------+------+ | login | type | +-------+------+ | test1 | A | | te ...
- 我的世界java版游戏角色名_我的世界:默认游戏角色中谁最帅?jeb成为了万众瞩目的那一个...
原标题:我的世界:默认游戏角色中谁最帅?jeb成为了万众瞩目的那一个 文/小编 大家好,我是小编,一个美貌与智慧并存的男子.前世的千百次轮回,才换得今生的一次相遇.为了让小伙伴们更好地了解游戏中的内容 ...
最新文章
- java executequery_关于Java怎样封装executeQuery()的问题
- 使用cpanel后台的“时钟守护作业”功能完成空间的定时全备份
- 2010年9月14日佛山大沥机楼网络故障日志
- 震惊!Canvas原来还能这么搞!代码画一个时钟出来
- 园区医保和其他地方的医保的区别
- 2020CCPC绵阳
- 在 CodeIgniter 中使用 jQuery 实现 AJAX
- 在10000以内判断一个整数,它加上100和加上268后都是一个完全平方数 3 提问:请问该数是多少?...
- 爱荷华大选 App 投票酿闹剧的反思:为什么我们在软件工程方面如此糟糕?
- Java fluent风格
- 建立项目接口文档_一个 SpringBoot 项目该包含哪些?
- 程序员工作交接文档怎么写_IT交接事项.doc
- 路由器wifi信号测试软件,常用路由器WIFI测速效果比对
- 51单片机 程序 红外发射 红外接收 红外双机通信 红外遥控器 控制 灯 系统 proteus 仿真
- 计算机主板电感有正负极么,功率电感有没有方向?正负极区分
- 【自由随想录(二)】
- linux+循环buffer,说说循环缓冲区(Ring Buffer)
- VirtualBox 虚拟电脑控制台错误
- TED-4-美好人生的定义
- CS61A Proj 3
热门文章
- css方式让div居于屏幕正中间
- php购物车面试题,php 购物车 细节
- JEWELCAD珠宝手饰设计视频教程 JewelCAD Pro v2.2.2
- linux进程管理工具supervisor安装卸载、子配置文件详解、遇到的问题、supervisor group群组管理、启动一个springboot项目示例、update命令注意点
- C语言之scanf超详细解析
- 【山科OJ】Problem D: 藏头诗
- 影牛社区短视频APP源码/最火短视频类APP源码下载
- 卸载命令行安装的ActivePerl
- 浅谈exp与expdp的区别
- 条码打印软件如何实现序列号循环打印