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 相关文章推荐
Oracle笔记
Apr 05 Oracle
oracle表分区的概念及操作
Apr 24 Oracle
ORACLE数据库应用开发的三十个注意事项
Jun 07 Oracle
快速学习Oracle触发器和游标
Jun 30 Oracle
详解Oracle块修改跟踪功能
Nov 07 Oracle
oracle重置序列从0开始递增1
Feb 28 Oracle
详解SQL的窗口函数
Apr 21 Oracle
分析SQL窗口函数之聚合窗口函数
Apr 21 Oracle
解决Oracle数据库用户密码过期
May 11 Oracle
oracle数据库去除重复数据
May 20 Oracle
在Oracle表中进行关键词搜索的过程
Jun 10 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
磨咖啡豆的密诀
2021/03/03 冲泡冲煮
攻克CakePHP系列三 表单数据增删改
2008/10/22 PHP
PHP--用万网的接口实现域名查询功能
2012/12/13 PHP
php代码中使用换行及(\n或\r\n和br)的应用
2013/02/02 PHP
php下载excel无法打开的解决方法
2013/12/24 PHP
dedecms中使用php语句指南
2014/11/13 PHP
js实现广告漂浮效果的小例子
2013/07/02 Javascript
JavaScript实现简单的时钟实例代码
2013/11/23 Javascript
javascript实现仿腾讯游戏选择
2015/05/14 Javascript
JS取模、取商及取整运算方法示例
2016/10/13 Javascript
Node.js中流(stream)的使用方法示例
2017/07/16 Javascript
二维码图片生成器QRCode.js简单介绍
2017/08/18 Javascript
AngularJS实现表单验证功能详解
2017/10/12 Javascript
使用vue-route 的 beforeEach 实现导航守卫(路由跳转前验证登录)功能
2018/03/22 Javascript
js 数组详细操作方法及解析合集
2018/06/01 Javascript
安装多版本Vue-CLI的实现方法
2020/03/24 Javascript
[01:32]2014DOTA2西雅图邀请赛 CIS我们有信心进入正赛
2014/07/08 DOTA
python常规方法实现数组的全排列
2015/03/17 Python
python使用post提交数据到远程url的方法
2015/04/29 Python
在Python中编写数据库模块的教程
2015/04/29 Python
深入理解NumPy简明教程---数组1
2016/12/17 Python
django 控制页面跳转的例子
2019/08/06 Python
Python 实现取多维数组第n维的前几位
2019/11/26 Python
python装饰器相当于函数的调用方式
2019/12/27 Python
Python通过递归函数输出嵌套列表元素
2020/10/15 Python
python 实现Harris角点检测算法
2020/12/11 Python
幼儿园教师辞职信
2014/01/18 职场文书
材料会计岗位职责
2014/03/06 职场文书
体育系毕业生求职自荐信
2014/04/16 职场文书
2014离婚协议书范文两篇
2014/09/15 职场文书
2015年世界环境日活动总结
2015/02/11 职场文书
酒店财务总监岗位职责
2015/04/03 职场文书
解约证明模板
2015/06/19 职场文书
原生JS实现飞机大战小游戏
2021/06/09 Javascript
JavaWeb 入门篇:创建Web项目,Idea配置tomcat
2021/07/16 Java/Android
如何vue使用el-table遍历循环表头和表体数据
2022/04/26 Vue.js