Oracle 数据仓库ETL技术之多表插入语句的示例详解


Posted in Oracle onApril 12, 2021

Oracle 数据仓库ETL技术之多表插入语句的示例详解

大家好!我是只谈技术不剪发的 Tony 老师。

ETL(提取、转换、加载)是指从源系统中提取数据并将其放入数据仓库的过程。Oracle 数据库为 ETL 流程提供了丰富的功能,今天我们就给大家介绍一下 Oracle 多表插入语句,也就是INSERT ALL 语句。

创建示例表

我们首先创建一个源数据表和三个目标表:

CREATE TABLE src_table(
  id INTEGER NOT NULL PRIMARY KEY,
  name VARCHAR2(10) NOT NULL
);
INSERT INTO src_table VALUES (1, '张三');
INSERT INTO src_table VALUES (2, '李四');
INSERT INTO src_table VALUES (3, '王五');

CREATE TABLE tgt_t1 AS
SELECT * FROM src_table WHERE 1=0;

CREATE TABLE tgt_t2 AS
SELECT * FROM src_table WHERE 1=0;

CREATE TABLE tgt_t3 AS
SELECT * FROM src_table WHERE 1=0;

无条件的 INSERT ALL 语句

INSERT ALL 语句可以用于将多行输入插入一个或者多个表中,因此也被称为多表插入语句。第一种形式的 INSERT ALL 语句是无条件的插入语句,源数据中的每一行数据都会被插入到每个目标表中。例如:

INSERT ALL
  INTO tgt_t1(id, name) VALUES(id, name)
  INTO tgt_t2(id, name) VALUES(id, name)
  INTO tgt_t3(id, name) VALUES(id, name)
SELECT * FROM src_table;

SELECT * FROM tgt_t1;
ID|NAME  |
--|------|
 1|张三  |
 2|李四  |
 3|王五  |

SELECT * FROM tgt_t2;
ID|NAME  |
--|------|
 1|张三  |
 2|李四  |
 3|王五  |

SELECT * FROM tgt_t3;
ID|NAME  |
--|------|
 1|张三  |
 2|李四  |
 3|王五  |

执行以上多表插入语句之后,三个目标表中都生成了 3 条记录。

我们也可以多次插入相同的表,实现一个插入语句插入多行数据的效果。例如:

TRUNCATE TABLE tgt_t1;

INSERT ALL
  INTO tgt_t1(id, name) VALUES(4, '赵六')
  INTO tgt_t1(id, name) VALUES(5, '孙七')
  INTO tgt_t1(id, name) VALUES(6, '周八')
SELECT 1 FROM dual;

SELECT * FROM tgt_t1;
ID|NAME  |
--|------|
 4|赵六  |
 5|孙七  |
 6|周八  |

在以上插入语句中,tgt_t1 出现了三次,最终在该表中插入了 3 条记录。这种语法和其他数据库中的以下多行插入语句效果相同:

-- MySQL、SQL Server、PostgreSQL以及SQLite
INSERT INTO tgt_t1(id, name)
VALUES(4, '赵六'), (5, '孙七'), (6, '周八');

另外,这种无条件的 INSERT ALL 语句还可以实现列转行(PIVOT)的功能。例如:

CREATE TABLE src_pivot(
  id INTEGER NOT NULL PRIMARY KEY,
  name1 VARCHAR2(10) NOT NULL,
  name2 VARCHAR2(10) NOT NULL,
  name3 VARCHAR2(10) NOT NULL
);
INSERT INTO src_pivot VALUES (1, '张三', '李四', '王五');

TRUNCATE TABLE tgt_t1;

INSERT ALL
  INTO tgt_t1(id, name) VALUES(id, name1)
  INTO tgt_t1(id, name) VALUES(id, name2)
  INTO tgt_t1(id, name) VALUES(id, name3)
SELECT * FROM src_pivot;

SELECT * FROM tgt_t1;
ID|NAME  |
--|------|
 1|张三  |
 1|李四  |
 1|王五  |

src_pivot 表中包含了 3 个名字字段,我们通过 INSERT ALL 语句将其转换 3 行记录。

有条件的 INSERT ALL 语句

第一种形式的 INSERT ALL 语句是有条件的插入语句,可以将满足不同条件的数据插入不同的表中。例如:

TRUNCATE TABLE tgt_t1;
TRUNCATE TABLE tgt_t2;
TRUNCATE TABLE tgt_t3;

INSERT ALL
  WHEN id <= 1 THEN
    INTO tgt_t1(id, name) VALUES(id, name)
  WHEN id BETWEEN 1 AND 2 THEN
    INTO tgt_t2(id, name) VALUES(id, name)
  ELSE
    INTO tgt_t3(id, name) VALUES(id, name)
SELECT * FROM src_table;

SELECT * FROM tgt_t1;
ID|NAME  |
--|------|
 1|张三  |
 
SELECT * FROM tgt_t2;
ID|NAME  |
--|------|
 1|张三  |
 2|李四  |

SELECT * FROM tgt_t3;
ID|NAME  |
--|------|
 3|王五  |

tgt_t1 中插入了 1 条数据,因为 id 小于等于 1 的记录只有 1 个。tgt_t2 中插入了 2 条数据,包括 id 等于 1 的记录。也就是说,前面的 WHEN 子句不会影响后续的条件判断,每个条件都会单独进行判断。tgt_t3 中插入了 1 条数据,ELSE 分支只会插入不满足前面所有条件的数据。

?有条件的多表插入语句最多支持 127 个 WHEN 子句。

有条件的 INSERT FIRST 语句

有条件的 INSERT FIRST 的原理和 CASE 表达式类似,只会执行第一个满足条件的插入语句,然后继续处理源数据中的其他记录。例如:

TRUNCATE TABLE tgt_t1;
TRUNCATE TABLE tgt_t2;
TRUNCATE TABLE tgt_t3;

INSERT FIRST
  WHEN id <= 1 THEN
    INTO tgt_t1(id, name) VALUES(id, name)
  WHEN id BETWEEN 1 AND 2 THEN
    INTO tgt_t2(id, name) VALUES(id, name)
  ELSE
    INTO tgt_t3(id, name) VALUES(id, name)
SELECT * FROM src_table;

SELECT * FROM tgt_t1;
ID|NAME  |
--|------|
 1|张三  |
 
SELECT * FROM tgt_t2;
ID|NAME  |
--|------|
 2|李四  |

SELECT * FROM tgt_t3;
ID|NAME  |
--|------|
 3|王五  |

以上语句和上一个示例的差别在于源数据中的每个记录只会插入一次,tgt_t2 中不会插入 id 等于 1 的数据。

多表插入语句的限制

Oracle 多表插入语句存在以下限制:

  • 多表插入只能针对表执行插入操作,不支持视图或者物化视图。
  • 多表插入语句不能通过 DB Link 针对远程表执行插入操作。
  • 多表插入语句不能通针对嵌套表执行插入操作。
  • 所有 INSERT INTO 子句中的字段总数量不能超过 999 个。
  • 多表插入语句中不能使用序列。多表插入语句被看作是单个语句,因此只会产生一个序列值并且用于所有的数据行,这样会导致数据问题。
  • 多表插入语句不能和执行计划稳定性功能一起使用。
  • 如果任何目标并使用了 PARALLEL 提示,整个语句都会被并行化处理。如果没有目标表使用 PARALLEL 提示,只有定义了 PARALLEL 属性的目标表才会被并行化处理。
  • 如果多表插入语句中的任何表是索引组织表,或者定义了位图索引,都不会进行并行化处理。

到此这篇关于Oracle 数据仓库 ETL 技术之多表插入语句的示例详解的文章就介绍到这了,更多相关Oracle 多表插入内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Oracle 相关文章推荐
zabbix agent2 监控oracle数据库的方法
May 13 Oracle
Oracle安装TNS_ADMIN环境变量设置参考
Nov 01 Oracle
Oracle表空间与权限的深入讲解
Nov 17 Oracle
详细聊聊Oracle表碎片对性能有多大的影响
Mar 19 Oracle
Lakehouse数据湖并发控制陷阱分析
Mar 31 Oracle
详解SQL的窗口函数
Apr 21 Oracle
分析SQL窗口函数之排名窗口函数
Apr 21 Oracle
清空 Oracle 安装记录并重新安装
Apr 26 Oracle
instantclient客户端 连接oracle数据库
Apr 26 Oracle
Oracle中DBLink的详细介绍
Apr 29 Oracle
在Oracle表中进行关键词搜索的过程
Jun 10 Oracle
Oracle中日期的使用方法实例
Jul 07 Oracle
Oracle笔记
Apr 05 #Oracle
oracle DGMGRL ORA-16603报错的解决方法(DG Broker)
Apr 06 #Oracle
ORACLE数据库对long类型字段进行模糊匹配的解决思路
oracle表分区的概念及操作
Apr 24 #Oracle
Oracle设置DB、监听和EM开机启动的方法
mybatis使用oracle进行添加数据的方法
Apr 27 #Oracle
使用springboot暴露oracle数据接口的问题
You might like
CakePHP去除默认显示的标题及图标的方法
2008/10/22 PHP
php站内搜索并高亮显示关键字的实现代码
2011/12/29 PHP
PHP分多步骤填写发布信息的简单方法实例代码
2012/09/23 PHP
PHP利用APC模块实现文件上传进度条的方法
2015/01/26 PHP
Yii2实现ajax上传图片插件用法
2016/04/28 PHP
学习从实践开始之jQuery插件开发 对话框插件开发
2012/04/26 Javascript
javascript动态加载三
2012/08/22 Javascript
jQuery登陆判断简单实现代码
2013/04/21 Javascript
JavaScript/Js脚本处理html元素的自定义属性解析(亲测兼容Firefox与IE)
2013/11/25 Javascript
Window.Open如何在同一个标签页打开
2014/06/20 Javascript
JavaScrip调试技巧之断点调试
2015/10/22 Javascript
浅谈js函数的多种定义方法与区别
2016/11/29 Javascript
详解有关easyUI的拖动操作中droppable,draggable用法例子
2017/06/03 Javascript
一篇文章让你彻底弄懂JS的事件冒泡和事件捕获
2017/08/14 Javascript
微信小程序 动画的简单实例
2017/10/12 Javascript
JS和JQuery实现雪花飘落效果
2017/11/30 jQuery
微信小程序通过保存图片分享到朋友圈功能
2018/05/24 Javascript
vue引入静态js文件的方法
2020/06/20 Javascript
[49:40]2018DOTA2亚洲邀请赛小组赛 A组加赛 TNC vs Newbee
2018/04/03 DOTA
Eclipse中Python开发环境搭建简单教程
2016/03/23 Python
浅谈python和C语言混编的几种方式(推荐)
2017/09/27 Python
在Mac上删除自己安装的Python方法
2018/10/29 Python
Python基础学习之基本数据结构详解【数字、字符串、列表、元组、集合、字典】
2019/06/18 Python
下载与当前Chrome对应的chromedriver.exe(用于python+selenium)
2020/01/14 Python
DjangoWeb使用Datatable进行后端分页的实现
2020/05/18 Python
基于python代码批量处理图片resize
2020/06/04 Python
少先队入队活动方案
2014/02/08 职场文书
学雷锋月活动总结
2014/04/25 职场文书
入党积极分子学习优秀共产党员先进事迹思想汇报
2014/09/13 职场文书
县政府领导班子“四风”方面突出问题整改措施
2014/09/23 职场文书
2014年房地产销售工作总结
2014/12/01 职场文书
主持人开场白台词
2015/05/29 职场文书
标枪加油稿
2015/07/22 职场文书
Python基础之字符串格式化详解
2021/04/21 Python
小程序wx.getUserProfile接口的具体使用
2021/06/02 Javascript
Mysql存储过程、触发器、事件调度器使用入门指南
2022/01/22 MySQL