欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 新闻 > 焦点 > 血缘解析<三>:如何解析DML语句?

血缘解析<三>:如何解析DML语句?

2025/5/2 18:40:17 来源:https://blog.csdn.net/nzbing/article/details/142525885  浏览:    关键词:血缘解析<三>:如何解析DML语句?

blood

  • 一、insert...select...on duplicate update...
  • 二、update...join...on...set...

本文案例只针对Mysql中的语句,其它数据库的DML语句可自行扩展

一、insert…select…on duplicate update…

eg:

insert into test (id,name,age)
select id,name,age from test1 ton duplicate key 
update id = t.id,name = t.name,age = t.age;

上述sql是Mysql的一段upsert逻辑

  • 获取目标表
SQLInsertStatement sqlInsertStatement = (SQLInsertStatement) statement;
String target_tab = sqlInsertStatement.getTableName().getSimpleName();
  • 获取源表、源字段、目标字段

上述insert语句的加工过程实际上是select部分,可单独获取select部分传入之前写好的解析select语句模块,详情可看血缘解析思路

  • 获取select部分
String sql_text = sqlInsertStatement.getQuery().toString();
if (sql_text != null) {Analyze.analyzSelect(sql_text, target_schema, target_tab);
}

二、update…join…on…set…

eg1:

update test ajoin test1 ton a.id = t.id set a.name = t.namea.age = t.age

上述sql是Mysql中最简单的用一张表更新另一种表字段的语句

  • 获取目标表
SQLUpdateStatement sqlUpdateStatement = (SQLUpdateStatement) statement;
String target_tab = sqlUpdateStatement.getTableName().getSimpleName();
  • 获取源表
SQLTableSource tablesource = sqlUpdateStatement.getTableSource();
if (tablesource instanceof SQLJoinTableSource) {tablesource = ((SQLJoinTableSource) tablesource).getRight();
}
  • 获取源字段、目标字段
List<SQLUpdateSetItem> col_lists = sqlUpdateStatement.getItems();
for (SQLUpdateSetItem col_list : col_lists) {target_col = col_list.getColumn().toString();if (target_col != null) {if (target_col.contains(".")) {target_col = target_col.substring(target_col.indexOf(".") + 1);}} else {target_col = "-";}source_col = col_list.getValue().toString();if (source_col != null) {if (source_col.contains(".")) {source_col = source_col.substring(source_col.indexOf(".") + 1);}} else {source_col = "-";}
}

上述代码可以获取到简单update语句的字段血缘关系,针对一些较复杂的语句,比如下述语句,应该如何处理呢?

update test2 ajoin (select a.id,a.name,b.age from test a join test1 b on a.id = b.id) ton a.id = t.id set a.name = t.namea.age = t.age

获取目标表、源表、源字段的方式和上述简单update语句的获取方式一样,区别是获取源表,这里的处理方式和上篇文章处理with cte语句的方式差不多;
join后面跟的是一段子查询,这个子查询可以当做一个临时表的加工过程,临时表我们可以自定义一个,比如target_tab + ‘join’,然后把子查询传入select解析模块,这时候获取到的血缘关系如下述表格:

target_tabtarget_colsource_tabsource_col
test2joinidtestid
test2joinnametestname
test2joinagetest1age

然后上述语句可以理解为解析:

update test2 ajoin test2join ton a.id = t.id set a.name = t.namea.age = t.age

这段语句和我们最开始分析最简单update语句结构是一样的,就可以按照上述方式处理,解析出来对应血缘关系为:

target_tabtarget_colsource_tabsource_col
test2idtest2joinid
test2nametest2joinname
test2agetest2joinage

最后可以通过递归获取最原始的血缘关系

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词