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数据库对long类型字段进行模糊匹配的解决思路
Apr 07 Oracle
oracle通过存储过程上传list保存功能
May 12 Oracle
zabbix agent2 监控oracle数据库的方法
May 13 Oracle
Oracle 区块链表创建过程详解
May 15 Oracle
Oracle11g r2 卸载干净重装的详细教程(亲测有效已重装过)
Jun 04 Oracle
Oracle以逗号分隔的字符串拆分为多行数据实例详解
Jul 16 Oracle
Oracle 死锁的检测查询及处理
Sep 25 Oracle
Oracle中DBLink的详细介绍
Apr 29 Oracle
Oracle锁表解决方法的详细记录
Jun 05 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
PHP初学者头疼问题总结
2006/10/09 PHP
改写ThinkPHP的U方法使其路由下分页正常
2014/07/02 PHP
php异步多线程swoole用法实例
2014/11/14 PHP
memcache一致性hash的php实现方法
2015/03/05 PHP
yii2使用GridView实现数据全选及批量删除按钮示例
2017/03/01 PHP
ThinkPHP框架实现数据增删改
2017/05/07 PHP
基于PHP实现发微博动态代码实例
2020/12/11 PHP
Nigma vs Alliance BO5 第五场2.14
2021/03/10 DOTA
JavaScript Base64编码和解码,实现URL参数传递。
2006/09/18 Javascript
JQuery Dialog的内存泄露问题解决方法
2010/06/18 Javascript
JS遍历Json字符串中键值对先转成JSON对象再遍历
2014/08/15 Javascript
JavaScript日期类型的一些用法介绍
2015/03/02 Javascript
JavaScript实现的多个图片广告交替显示效果代码
2015/09/04 Javascript
Angular中$compile源码分析
2016/01/28 Javascript
浅谈Javascript事件对象
2017/02/05 Javascript
解决微信二次分享不显示摘要和图片的问题
2017/08/18 Javascript
vue的无缝滚动组件vue-seamless-scroll实例
2017/12/18 Javascript
jQuery实现的手动拖动控制进度条效果示例【测试可用】
2018/04/18 jQuery
Chart.js 轻量级HTML5图表绘制工具库(知识整理)
2018/05/22 Javascript
jquery ajaxfileuplod 上传文件 essyui laoding 效果【防止重复上传文件】
2018/05/26 jQuery
vue组件库的在线主题编辑器的实现思路
2020/04/03 Javascript
[02:00]DOTA2英雄COSPLAY闹市街头巡游助威2015国际邀请赛
2015/08/02 DOTA
[25:45]2018DOTA2亚洲邀请赛4.5SOLO赛 Sylar vs Paparazi
2018/04/06 DOTA
Python实现的飞速中文网小说下载脚本
2015/04/23 Python
Linux 发邮件磁盘空间监控(python)
2016/04/23 Python
python_opencv用线段画封闭矩形的实例
2018/12/05 Python
通过pycharm使用git的步骤(图文详解)
2019/06/13 Python
Python实现AI自动抠图实例解析
2020/03/05 Python
python 实用工具状态机transitions
2020/11/21 Python
天巡全球:Skyscanner Global
2017/06/20 全球购物
家得宝墨西哥官网:The Home Depot墨西哥
2019/11/18 全球购物
环保倡议书怎么写
2014/05/16 职场文书
中韩经贸翻译专业大学生职业生涯规划范文
2014/09/18 职场文书
python编程实现清理微信重复缓存文件
2021/11/01 Python
MyBatis核心源码深度剖析SQL语句执行过程
2022/05/20 Java/Android
基于Python实现西西成语接龙小助手
2022/08/05 Golang