导语

因为项目中要做跨数据源的数据分析功能,所以使用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语句中的表名相关推荐

  1. mysql 批量替换 所有表_[收藏]批量替换一个数据库中所有表中所有记录

    /***********批量替换一个数据库中所有表中所有记录************/ declare @delStr nvarchar(500) set @delStr='这里是要替换的字符' /* ...

  2. sql跨表查询_白话django之ORM的查询语句

    教程源码:z991/django_turital 在日常开发中,数据库的增删改查(CDUR)中,查询需求偏多,所以查询的语法比增删改操作多得多,尤其是跨表关联查询,可以让代码精简很多年. 直接上代码吧 ...

  3. sql活动监视器 死锁_使用system_health扩展事件监视SQL Server死锁

    sql活动监视器 死锁 Performance monitoring is a must to do the task for a DBA. You should ensure that the da ...

  4. sql server jar包_老王,怎么完整SQL的显示日志,而不是???...

    点击蓝色"Java面试那些事儿"关注我哟 加个"星标",优质文章,第一时间送达 来源:http://1t.click/ag6q在常规项目的开发中可能最容易出问题 ...

  5. sql 占比计算_数据库索引的优化及SQL处理过程(建议收藏)

    想要设计出好的索引,首先必须了解SQL语句在数据库服务器中的处理过程,本文介绍 数据库索引设计与优化 中几个对索引优化非常重要的概念. 谓词 谓词就是条件表达式. SQL语句的where子句由一个或者 ...

  6. Java 错误:找不到或无法加载主类(源文件中含有包名 package)

    1. 问题定位 编译(javac)和执行(java)java 程序时,出现这种类型的错误:找不到或无法加载主类: 首先排除是否是环境变量配置不当造成的问题,只要保证,命令行界面能够识别 javac/j ...

  7. mongo 改字段名_一日一技:修改MongoDB集合中的字段名

    一日一技:修改MongoDB集合中的字段名 一日一技是一个每天更新的栏目,旨在使用3分钟的时间让你每天都有新的进步. 在我们使用MongoDB的过程中,经常会出现修改数据的情况.我们一般使用 upda ...

  8. python合法的变量名有哪些_中国大学MOOC: 以下不是Python中合法变量名的是______。...

    中国大学MOOC: 以下不是Python中合法变量名的是______. 答:5MyGod "32位微型计算机"中的32指的是( ) 答:机器字长 以下是细胞因子治疗肿瘤的特点的是: ...

  9. java sql查询空内容_返回null值而不是sql查询中的空集

    比方说,有两个表: select * from users; +-------+------+ | login | type | +-------+------+ | test1 | A | | te ...

  10. 我的世界java版游戏角色名_我的世界:默认游戏角色中谁最帅?jeb成为了万众瞩目的那一个...

    原标题:我的世界:默认游戏角色中谁最帅?jeb成为了万众瞩目的那一个 文/小编 大家好,我是小编,一个美貌与智慧并存的男子.前世的千百次轮回,才换得今生的一次相遇.为了让小伙伴们更好地了解游戏中的内容 ...

最新文章

  1. java executequery_关于Java怎样封装executeQuery()的问题
  2. 使用cpanel后台的“时钟守护作业”功能完成空间的定时全备份
  3. 2010年9月14日佛山大沥机楼网络故障日志
  4. 震惊!Canvas原来还能这么搞!代码画一个时钟出来
  5. 园区医保和其他地方的医保的区别
  6. 2020CCPC绵阳
  7. 在 CodeIgniter 中使用 jQuery 实现 AJAX
  8. 在10000以内判断一个整数,它加上100和加上268后都是一个完全平方数 3 提问:请问该数是多少?...
  9. 爱荷华大选 App 投票酿闹剧的反思:为什么我们在软件工程方面如此糟糕?
  10. Java fluent风格
  11. 建立项目接口文档_一个 SpringBoot 项目该包含哪些?
  12. 程序员工作交接文档怎么写_IT交接事项.doc
  13. 路由器wifi信号测试软件,常用路由器WIFI测速效果比对
  14. 51单片机 程序 红外发射 红外接收 红外双机通信 红外遥控器 控制 灯 系统 proteus 仿真
  15. 计算机主板电感有正负极么,功率电感有没有方向?正负极区分
  16. 【自由随想录(二)】
  17. linux+循环buffer,说说循环缓冲区(Ring Buffer)
  18. VirtualBox 虚拟电脑控制台错误
  19. TED-4-美好人生的定义
  20. CS61A Proj 3

热门文章

  1. css方式让div居于屏幕正中间
  2. php购物车面试题,php 购物车 细节
  3. JEWELCAD珠宝手饰设计视频教程 JewelCAD Pro v2.2.2
  4. linux进程管理工具supervisor安装卸载、子配置文件详解、遇到的问题、supervisor group群组管理、启动一个springboot项目示例、update命令注意点
  5. C语言之scanf超详细解析
  6. 【山科OJ】Problem D: 藏头诗
  7. 影牛社区短视频APP源码/最火短视频类APP源码下载
  8. 卸载命令行安装的ActivePerl
  9. 浅谈exp与expdp的区别
  10. 条码打印软件如何实现序列号循环打印