Oracle 多表 INSERT 支援 INSERT ALL 搭配 SELECT 子句,實現「一讀多寫」與「行轉列」旋轉插入。本文透過銷售表轉月度統計表範例,示範旋轉 INSERT 完整流程。
CREATE TABLE sales_tbl (
id NUMBER PRIMARY KEY,
jan NUMBER,
feb NUMBER,
mar NUMBER,
apr NUMBER
);
INSERT INTO sales_tbl VALUES (1, 100, 200, 300, 400);
INSERT INTO sales_tbl VALUES (2, 110, 120, 130, 140);
-- 來源資料
ID JAN FEB MAR APR
1 100 200 300 400
2 110 120 130 140
CREATE TABLE monthly_sales_stats (
seq_no NUMBER,
month_name VARCHAR2(10),
avg_sales NUMBER,
sum_sales NUMBER
);
INSERT ALL
INTO monthly_sales_stats VALUES (1, '一月', avg1, sum1)
INTO monthly_sales_stats VALUES (2, '二月', avg2, sum2)
INTO monthly_sales_stats VALUES (3, '三月', avg3, sum3)
INTO monthly_sales_stats VALUES (4, '四月', avg4, sum4)
SELECT AVG(jan) avg1, SUM(jan) sum1,
AVG(feb) avg2, SUM(feb) sum2,
AVG(mar) avg3, SUM(mar) sum3,
AVG(apr) avg4, SUM(apr) sum4
FROM sales_tbl;
4 rows created.
SEQ_NO MONTH_NAME AVG_SALES SUM_SALES
1 一月 105 210
2 二月 160 320
3 三月 215 430
4 四月 270 540
SELECT 子句只掃描一次 sales_tbl,計算 8 個彙總值INSERT ALL 將每個 INTO 子句視為獨立插入操作,共插入 4 筆WHEN 子句實現條件式多表插入(INSERT ALL/WHEN ... THEN ... ELSE ...)
INSERT ALL
WHEN avg_sales > 150 THEN
INTO high_perf_months VALUES (month_name, avg_sales, sum_sales)
WHEN avg_sales <= 150 THEN
INTO low_perf_months VALUES (month_name, avg_sales, sum_sales)
ELSE
INTO other_months VALUES (month_name, avg_sales, sum_sales)
SELECT AVG(jan) avg_sales, SUM(jan) sum_sales, '一月' month_name FROM sales_tbl UNION ALL
SELECT AVG(feb), SUM(feb), '二月' FROM sales_tbl UNION ALL
SELECT AVG(mar), SUM(mar), '三月' FROM sales_tbl UNION ALL
SELECT AVG(apr), SUM(apr), '四月' FROM sales_tbl;
INTO 子句INSERT FIRST:滿足第一個 WHEN 條件即停止評估後續條件INSERT ALL:評估所有 WHEN 條件,可能插入多張表ALTER SESSION ENABLE PARALLEL DML 後可提升大量資料效能| 方式 | 掃描次數 | 解析次數 | 適用資料量 |
|---|---|---|---|
| 4 次獨立 INSERT | 4 | 4 | 小 |
| INSERT ALL 旋轉 | 1 | 1 | 中大型 |
| CTAS + 交換分區 | 1 | 1 | 超大型 |