Oracle 數據倉庫ETL技術之多表插入語句的示例詳解

dwh

大傢好!我是隻談技術不剪發的 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 多表插入內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀:

    None Found