Oracle **外部表** 讓資料庫能直接用 SQL 查詢作業系統檔案 (文本、CSV、定寬、JSON 等),無需載入、無需外部程式。本文以「查詢 Alert Log」為核心場景,完整演示外部表建立、目錄物件授權、查詢語法、錯誤過濾與進階應用。
ORACLE_LOADER (文本/CSV/定寬)、ORACLE_DATAPUMP (二進位 Dump)、ORACLE_HDFS/ORACLE_HIVE (大數據)。$ mkdir -p /u01/app/oracle/ext_data
$ cat > /u01/app/oracle/ext_data/ext.dat <<'EOF'
10,20,30
40,50,60
70,80,90
EOF
CREATE USER ext_user IDENTIFIED BY "ext123"
DEFAULT TABLESPACE users QUOTA UNLIMITED ON users;
GRANT CREATE SESSION, CREATE TABLE, CREATE ANY DIRECTORY TO ext_user;
CONN ext_user/ext123
CREATE OR REPLACE DIRECTORY ext_dir AS '/u01/app/oracle/ext_data';
CREATE TABLE ext_table (
id NUMBER,
val1 NUMBER,
val2 NUMBER
)
ORGANIZATION EXTERNAL (
TYPE ORACLE_LOADER
DEFAULT DIRECTORY ext_dir
ACCESS PARAMETERS (
RECORDS DELIMITED BY NEWLINE
FIELDS TERMINATED BY ','
MISSING FIELD VALUES ARE NULL
REJECT ROWS WITH ALL NULL FIELDS
)
LOCATION ('ext.dat')
)
REJECT LIMIT UNLIMITED; -- 或具體數字
SQL> SELECT * FROM ext_table;
ID VAL1 VAL2
--- ----- -----
10 20 30
40 50 60
70 80 90
SQL> SHOW PARAMETER background_dump_dest;
-- 或 11g+:
SELECT value FROM v$diag_info WHERE name = 'Diag Trace';
-- 典型路徑: /u01/app/oracle/diag/rdbms/orcl/orcl/trace/alert_orcl.log
CREATE OR REPLACE DIRECTORY alert_dir AS '/u01/app/oracle/diag/rdbms/orcl/orcl/trace';
-- 需確保 OS 層 oracle 使用者對該目錄有讀取權限
CREATE TABLE alert_log_ext (
log_line VARCHAR2(4000)
)
ORGANIZATION EXTERNAL (
TYPE ORACLE_LOADER
DEFAULT DIRECTORY alert_dir
ACCESS PARAMETERS (
RECORDS DELIMITED BY NEWLINE
NOBADFILE NOLOGFILE NODISCARDFILE -- 避免產生額外檔案
)
LOCATION ('alert_orcl.log')
)
REJECT LIMIT UNLIMITED;
-- 4a. 最近 50 行
SELECT * FROM alert_log_ext WHERE ROWNUM <= 50;
-- 4b. 過濾 ORA- 錯誤 (核心價值)
SELECT log_line FROM alert_log_ext
WHERE log_line LIKE 'ORA-%'
ORDER BY ROWNUM; -- 無排序保證,若需時間序需解析時間戳
-- 4c. 過濾特定錯誤代碼
SELECT log_line FROM alert_log_ext
WHERE log_line LIKE '%ORA-01555%'; -- Snapshot too old
-- 4d. 統計錯誤頻率 (簡易)
SELECT SUBSTR(log_line, 1, 9) AS err_code, COUNT(*)
FROM alert_log_ext
WHERE log_line LIKE 'ORA-%'
GROUP BY SUBSTR(log_line, 1, 9)
ORDER BY 2 DESC;
-- Alert Log 格式: "Mon Jan 01 10:00:00 2024"
-- 建立視圖解析時間戳
CREATE OR REPLACE VIEW alert_log_parsed AS
SELECT
log_line,
TO_TIMESTAMP(
REGEXP_SUBSTR(log_line, '^\w{3}\s+\w{3}\s+\d{1,2}\s+\d{2}:\d{2}:\d{2}\s+\d{4}'),
'Dy Mon DD HH24:MI:SS YYYY'
) AS log_time
FROM alert_log_ext
WHERE REGEXP_LIKE(log_line, '^\w{3}\s+\w{3}\s+\d{1,2}\s+\d{2}:\d{2}:\d{2}\s+\d{4}');
-- 現在可時間範圍查詢
SELECT * FROM alert_log_parsed
WHERE log_time >= SYSDATE - 1
AND log_line LIKE 'ORA-%';
alert_.log )LOCATION ('alert_1.log', 'alert_2.log')V$DIAG_ALERT_EXT (12c+ 內建視圖,自動聚合所有實例)-- 建立排程作業 (DBMS_SCHEDULER) 定期查詢新錯誤
BEGIN
DBMS_SCHEDULER.CREATE_JOB(
job_name => 'MONITOR_ALERT_ERRORS',
job_type => 'PLSQL_BLOCK',
job_action => q'[
DECLARE
v_count NUMBER;
BEGIN
SELECT COUNT(*) INTO v_count
FROM alert_log_ext
WHERE log_line LIKE 'ORA-%'
AND log_time > (SELECT MAX(last_check) FROM alert_monitor_log);
IF v_count > 0 THEN
-- 發送郵件/簡訊/寫入監控表
INSERT INTO alert_monitor_log(check_time, error_count) VALUES (SYSDATE, v_count);
END IF;
END;
]',
start_date => SYSTIMESTAMP,
repeat_interval => 'FREQ=MINUTELY; INTERVAL=5',
enabled => TRUE
);
END;
/
READ 於目錄物件:GRANT READ ON DIRECTORY alert_dir TO monitor_user;| 錯誤 | 原因 | 解決 |
|---|---|---|
| ORA-29913 / KUP-04040 | 檔案不存在或路徑錯誤 | 檢查 DIRECTORY 路徑、OS 權限、檔案名大小寫 |
| ORA-29913 / KUP-01005 | 存取參數語法錯誤 | 驗證 ACCESS PARAMETERS 子句,參考文件範例 |
| 查無資料 | 檔案編碼非預設 (AL32UTF8) | 指定 CHARACTERSET AL32UTF8 或實際字符集 |
| 效能極差 | 大檔案全掃描、無並行 | 拆分檔案、啟用 PARALLEL、或用 V$DIAG_ALERT_EXT |
外部表是 DBA 「零程式碼、純 SQL」查詢 OS 檔案的利器。以 Alert Log 為例,建立一次外部表,即可永久享受 WHERE log_line LIKE 'ORA-%'、時間範圍過濾、錯誤統計、自動化監控等能力。配合 12c+ V$DIAG_ALERT_EXT 內建視圖、正則解析時間戳、DBMS_SCHEDULER 自動化,構建企業級資料庫日誌智能監控體系。