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

server/2024/10/19 21:34:17/

blood

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

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

一、insert…select…on duplicate update…

eg:

sql">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逻辑

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

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

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

二、update…join…on…set…

eg1:

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

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

  • 获取目标表
java">SQLUpdateStatement sqlUpdateStatement = (SQLUpdateStatement) statement;
String target_tab = sqlUpdateStatement.getTableName().getSimpleName();
  • 获取源表
java">SQLTableSource tablesource = sqlUpdateStatement.getTableSource();
if (tablesource instanceof SQLJoinTableSource) {tablesource = ((SQLJoinTableSource) tablesource).getRight();
}
  • 获取源字段、目标字段
java">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语句的字段血缘关系,针对一些较复杂的语句,比如下述语句,应该如何处理呢?

sql">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

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

sql">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

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


http://www.ppmy.cn/server/123052.html

相关文章

Text-to-SQL方法研究

1、面临的挑战 自然语言问题往往包含复杂的语言结构,如嵌套语句、倒装句和省略等,很难准确映射到SQL查询上。此外,自然语言本身就存在歧义,一个问题可能有多种解读。消除歧义需要深入的语言理解能力以及融入上下文和领域知识。 要生成正确的SQL查询,文本到SQL系统需要全面理解…

基于单片机的小车行走加温湿度检测系统

目录 一、主要功能 二、硬件资源 三、程序编程 四、实现现象 一、主要功能 基于51单片机&#xff0c;采样DHT11温湿度传感器检测温湿度&#xff0c;滑动变阻器连接数码转换器模拟电量采集传感器&#xff0c; 电机采样L298N驱动&#xff0c;各项参数通过LCD1602显示&#x…

逆变器控制技术

内容只能用来简单的让你对逆变器有个感性的认识。 文章目录 逆变器控制技术深度解析与应用实践逆变器的基本原理逆变器的控制算法PWM调制PID控制 逆变器控制软件设计软件实现示例 应用场景结论&#x1f6e0;️ 逆变器在不同应用场景下的设计考虑有哪些&#xff1f;太阳能发电系…

C++学习,STL

C标准模板库&#xff08;Standard Template Library&#xff0c;简称STL&#xff09;是C编程语言中的一组高度灵活且高效的通用算法和数据结构集合。STL极大地简化了常见编程任务&#xff0c;如容器管理、算法应用和迭代器使用。 STL主要由以下几个组件组成&#xff1a; 容器&…

数据采集使用动态代理被拦截的原因是什么?

最近经常刷到关于数据采集使用动态代理被拦截的话题&#xff0c;许多朋友对这个问题感到困惑。那么&#xff0c;今天我们一起来聊聊这个话题&#xff0c;帮助大家更好地理解其中的原因。 动态代理是什么&#xff1f; 首先&#xff0c;我们得了解一下动态代理的概念。动态代理…

STM32CUBEIDE FreeRTOS操作教程(五):mutex互斥信号量

STM32CUBEIDE FreeRTOS操作教程&#xff08;五&#xff09;&#xff1a;mutex互斥信号量 STM32CUBE开发环境集成了STM32 HAL库进行FreeRTOS配置和开发的组件&#xff0c;不需要用户自己进行FreeRTOS的移植。这里介绍最简化的用户操作类应用教程。以STM32F401RCT6开发板为例&am…

H.264编码介绍

一、简介 H.264,又称为AVC(Advanced Video Coding),是一种广泛使用的视频压缩标准。它由国际电信联盟(ITU)和国际标准化组织(ISO)联合开发,并于2003年发布。 H.264的发展历史可以追溯到上个世纪90年代。当时,视频压缩技术的主要标准是MPEG-2,但它在压缩率和视频质…

Ubuntu网卡配置

一、低阶版本配置网卡步骤:(如Ubuntu 16.04.2 LTS) 编辑配置文件interfaces,添加网卡配置信息 我这边以root用户登录进服务器,就不需要普通用户每次在命令前添加sudo vim /etc/network/interfaces 1.动态获取ip设置: auto ens3 # 网卡设备名称ens3 iface ens3 ine…