「每天 10 問」系列沉澱了大量實戰高頻問題。本文整理第 5 期 10 題,補充原理、版本差異、最佳實務與避坑指南,構建可檢索的知識卡片庫。
-- 表註釋
COMMENT ON TABLE emp IS '員工主檔表';
-- 欄位註釋
COMMENT ON COLUMN emp.ename IS '員工姓名';
-- 查詢所有有註釋的表
SELECT table_name, comments FROM user_tab_comments WHERE comments IS NOT NULL;
-- 查詢欄位註釋
SELECT table_name, column_name, comments FROM user_col_comments WHERE comments IS NOT NULL;
最佳實務:納入開發規範,DDL 變更必伴隨註釋更新;利用 DBMS_METADATA.GET_DDL 導出時自動包含註釋;Data Dictionary 註釋是元資料治理基石。
-- 標準查詢 (含使用率、剩餘、自動擴展資訊)
SELECT
d.tablespace_name,
ROUND(SUM(d.bytes)/1024/1024,2) AS total_mb,
ROUND(SUM(NVL(f.bytes,0))/1024/1024,2) AS free_mb,
ROUND((1 - SUM(NVL(f.bytes,0))/SUM(d.bytes))*100,2) AS used_pct,
MAX(d.autoextensible) AS autoextensible
FROM dba_data_files d
LEFT JOIN dba_free_space f ON f.file_id = d.file_id
GROUP BY d.tablespace_name
ORDER BY used_pct DESC;
進階:加入 DBA_TEMP_FILES 統計臨時表空間;結合 DBA_TABLESPACE_USAGE_METRICS (12c+) 獲取即時使用率含 Undo/Temp。
init.ora / spfile 參數:
# 啟用 MTS (共享伺服器)
DISPATCHERS="(PROTOCOL=TCP)(SERVICE=ORA9I_XDB)" -- 至少一行 DISPATCHERS 即啟用 MTS
SHARED_SERVERS=5 -- 啟動時預啟動共享伺服器進程數
MAX_SHARED_SERVERS=50 -- 最大共享伺服器進程數
SHARED_SERVER_SESSIONS=200 -- 最大共享伺服器 Session 數
CIRCUITS=1000 -- 最大虛擬電路數
# 停用 MTS (回專用伺服器) - 註釋或移除所有 DISPATCHERS 參數
# DISPATCHERS="(PROTOCOL=TCP)(SERVICE=ORA9I_XDB)"
動態調整:ALTER SYSTEM SET SHARED_SERVERS=10 SCOPE=BOTH; (無需重啟)。適用場景:高併發、長連接、記憶體受限 (C/S 兩層);不適用:短連接、高 CPU 密集運算、三層架構連接池 (已在應用層池化)。
-- 方法 1: X$ 表 (需 SYS)
SELECT MAX(ktuxescnw * POWER(2,32) + ktuxescnb) AS current_scn FROM x$ktuxe;
-- 方法 2: V$DATABASE (10g+)
SELECT current_scn FROM v$database;
-- 方法 3: DBMS_FLASHBACK (10g+)
SELECT DBMS_FLASHBACK.GET_SYSTEM_CHANGE_NUMBER FROM dual;
-- 方法 4: 近似 SCN (無需高權限)
SELECT dbms_flashback.get_system_change_number FROM dual;
用途:時間點恢復、Data Guard 同步進度、閃回查詢基準、分散式交易協調。
| 版本 | 函數 | 精度 | 回傳型別 |
|---|---|---|---|
| 9i 以前 | 無原生支援 | 秒 | DATE |
| 9i ~ 11g | SYSTIMESTAMP | 微秒 (FF6) | TIMESTAMP WITH TIME ZONE |
| 12c+ | SYSTIMESTAMP, SYSDATE (仍秒) | 微秒 | TIMESTAMP WITH TIME ZONE |
SELECT SYSTIMESTAMP FROM dual;
-- 輸出: 2024-01-15 14:30:45.123456 +08:00
SELECT TO_CHAR(SYSTIMESTAMP, 'YYYY-MM-DD HH24:MI:SS.FF6') FROM dual;
-- 2024-01-15 14:30:45.123456
注意:SYSDATE 永遠只精確到秒,高併發主鍵生成勿用。
-- CHR(10) = Line Feed (LF, Unix 換行)
-- CHR(13) = Carriage Return (CR, Windows 換行需 CR+LF)
SELECT 'Welcome to visit' || CHR(10) || 'www.CSDN.NET' FROM dual;
-- 跨平台安全寫法
SELECT 'Line 1' || CHR(13) || CHR(10) || 'Line 2' FROM dual;
應用:PL/SQL 產生郵件內容、報表標題、日誌格式化。
| 版本 | 預設排序 | 支援規則 | NLS_SORT 設定值 |
|---|---|---|---|
| 9i 以前 | 二進制編碼順序 (GBK 碼序) | 無 | BINARY (預設) |
| 9i+ | 可選語言排序 | 拼音、部首筆畫、筆畫部首 | SCHINESE_PINYIN_M (拼音)SCHINESE_RADICAL_M (部首->筆畫)SCHINESE_STROKE_M (筆畫->部首) |
-- Session 級設定
ALTER SESSION SET NLS_SORT = SCHINESE_PINYIN_M;
ALTER SESSION SET NLS_COMP = LINGUISTIC; -- 啟用語言比較 (影響 WHERE/ORDER BY)
-- 查詢驗證
SELECT * FROM chinese_table ORDER BY name; -- 依拼音排序
效能:語言排序無法使用標準 B-Tree 索引 (需語言索引 NLSSORT 函數式索引),大表排序建議應用層處理或建立語言索引。
可行:CREATE TABLE "員工表" ("姓名" VARCHAR2(20)); (需雙引號保留大小寫/特殊字元)。
強烈不建議:
COMMENT 存中文業務含義。編輯 $ORACLE_HOME/sqlplus/admin/glogin.sql (全域) 或 login.sql (用戶目錄):
-- 常用設定
SET LINESIZE 200
SET PAGESIZE 1000
SET LONG 1000000
SET LONGC 1000000
SET TRIMSPOOL ON
SET TRIMOUT ON
SET TIMING ON
SET TIME ON
SET SQLPROMPT "_USER'@'_CONNECT_IDENTIFIER> "
COLUMN sql_text FORMAT A100 WRAP
COLUMN plan_table_output FORMAT A120
-- 自動執行腳本
@/home/oracle/scripts/set_env.sql
每次 SQL*Plus 啟動自動執行,建立統一團隊環境。
| 層級 | 方法 | 範例 | 生效範圍 |
|---|---|---|---|
| Session | ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD HH24:MI:SS'; | 含時分秒 | 當前 Session |
| 實例 (靜態) | init.ora / spfile 增加 NLS_DATE_FORMAT = 'YYYY-MM-DD HH24:MI:SS' | 全實例預設 | 需重啟 (靜態參數) |
| 實例 (動態, 11g+) | ALTER SYSTEM SET NLS_DATE_FORMAT = '...' SCOPE=SPFILE; | 全實例預設 | 下次重啟生效 |
| 環境變數 | 客戶端 NLS_LANG 含語言地區,間接影響 | AMERICAN_AMERICA.ZHS16GBK | 客戶端 Session |
建議:應用層統一用 TO_DATE/TO_CHAR 顯式指定格式,不依賴隱性 NLS_DATE_FORMAT,避免跨環境行為不一致。
這 10 問覆蓋元資料管理、空間監控、架構模式、SCN/時間精度、字串操作、國際化排序、命名規範、工具配置、日期格式——構成 DBA/開發日常 90% 高頻操作。建議將每題製作成「知識卡片」 (問題、標準答案、原理、版本差異、避坑、腳本),納入團隊 Wiki,新人入職自學、資深巡檢核對。