表 A (CLM001 PK, SCORE) 初始分數為 0。表 B (ID, CLM001, SCORE) 含多筆明細。需將表 B 依 CLM001 分組求和,加至表 A 對應記錄的 SCORE。
範例資料:
| 表 A | |
|---|---|
| CLM001 | SCORE |
| 001 | 0 |
| 002 | 0 |
| 003 | 0 |
| 004 | 0 |
| 表 B | ||
|---|---|---|
| ID | CLM001 | SCORE |
| 0 | 001 | 12 |
| 1 | 001 | 24 |
| 2 | 002 | 110 |
| 3 | 004 | 220 |
| 4 | 004 | 20 |
預期結果:A 表 001→36、002→110、003→0、004→240。
WITH r AS (
SELECT CLM001, SUM(SCORE) AS total
FROM B
GROUP BY CLM001
)
UPDATE A
SET SCORE = (SELECT total FROM r WHERE r.CLM001 = A.CLM001)
WHERE EXISTS (SELECT 1 FROM r WHERE r.CLM001 = A.CLM001);
CREATE OR REPLACE PROCEDURE p_test AS
v_clm001 A.CLM001%TYPE;
CURSOR c_record IS SELECT DISTINCT CLM001 FROM B;
BEGIN
OPEN c_record;
LOOP
FETCH c_record INTO v_clm001;
EXIT WHEN c_record%NOTFOUND;
UPDATE A
SET SCORE = (SELECT SUM(SCORE) FROM B WHERE CLM001 = v_clm001)
WHERE CLM001 = v_clm001;
END LOOP;
CLOSE c_record;
END;
/
UPDATE A
SET SCORE = SCORE + (
SELECT SUM(SCORE)
FROM B
WHERE B.CLM001 = A.CLM001
)
WHERE EXISTS (SELECT 1 FROM B WHERE B.CLM001 = A.CLM001);
MERGE INTO A
USING (SELECT CLM001, SUM(SCORE) AS total FROM B GROUP BY CLM001) B_agg
ON (A.CLM001 = B_agg.CLM001)
WHEN MATCHED THEN UPDATE SET A.SCORE = A.SCORE + B_agg.total;
或建立視圖簡化:
CREATE VIEW B_SUM AS SELECT CLM001, SUM(SCORE) AS total FROM B GROUP BY CLM001;
UPDATE A SET SCORE = SCORE + (SELECT total FROM B_SUM WHERE CLM001 = A.CLM001)
WHERE EXISTS (SELECT 1 FROM B_SUM WHERE CLM001 = A.CLM001);
-- 1. 建立測試資料(100萬筆 B 表)
CREATE TABLE B AS
SELECT ROWNUM ID, MOD(ROWNUM, 10000) CLM001, DBMS_RANDOM.VALUE(1,100) SCORE
FROM DUAL CONNECT BY LEVEL <= 1000000;
-- 2. 收集統計
EXEC DBMS_STATS.GATHER_TABLE_STATS(USER, 'B');
EXEC DBMS_STATS.GATHER_TABLE_STATS(USER, 'A');
-- 3. 開啟 SQL Trace
ALTER SESSION SET SQL_TRACE = TRUE;
-- 4. 執行各方案,比較:
-- - Elapsed Time
-- - Consistent Gets
-- - Physical Reads
-- - Plan Hash Value
| 場景 | 推薦寫法 | 關鍵索引 |
|---|---|---|
| 中小資料量、一次性腳本 | 相關子查詢 UPDATE | B.CLM001 |
| 大量資料、定期排程 | MERGE + 聚合視圖 | B.CLM001, A.CLM001 |
| 需複雜業務邏輯、錯誤處理 | PL/SQL 批次處理 | 同上 + 批次大小控制 |
| 跨資料庫/異構更新 | DB Link + MERGE | 遠端索引同步 |
SCORE = SCORE + 子查詢 累加CLM001 索引SELECT ... FOR UPDATE 或序列化「用集合思維寫 SQL,用視圖封裝邏輯,用 MERGE 實現高效更新」—— 這是 Oracle 開發者的進階心法。