Oracle 12c 新 SQL 特性详解
Oracle 12c 新 SQL 特性详解
适用版本:Oracle Database 12c / 19c / 23ai 文档版本:v1.0 / 2026-07
1. 概述
Oracle 12c 引入大量新 SQL 特性[1]:
详细见:Oracle 12c 新 SQL 特性。
2. FETCH 分页
2.1 基本
SELECT * FROM employees ORDER BY id
OFFSET 100 ROWS FETCH NEXT 10 ROWS ONLY;
2.2 百分比
SELECT * FROM employees ORDER BY salary DESC
FETCH FIRST 10 PERCENT ROWS ONLY;
2.3 WITH TIES
SELECT * FROM employees ORDER BY salary DESC
FETCH FIRST 10 ROWS WITH TIES;
详细见:Oracle SQL 查询优化技巧。
3. IDENTITY
3.1 基本
CREATE TABLE employees (
id NUMBER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
name VARCHAR2(100)
);
-- BY DEFAULT
CREATE TABLE employees (
id NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
name VARCHAR2(100)
);
-- ON NULL
CREATE TABLE employees (
id NUMBER GENERATED BY DEFAULT ON NULL AS IDENTITY PRIMARY KEY,
name VARCHAR2(100)
);
3.2 选项
CREATE TABLE employees (
id NUMBER GENERATED ALWAYS AS IDENTITY
(START WITH 1 INCREMENT BY 1 MAXVALUE 999999 CACHE 20)
PRIMARY KEY
);
详细见:Oracle 序列与自增列详解。
4. 临时表
4.1 Private Temporary(18c+)
CREATE PRIVATE TEMPORARY TABLE ora$ptt_temp (
id NUMBER,
name VARCHAR2(100)
) ON COMMIT DROP DEFINITION;
-- 或 ON COMMIT PRESERVE DEFINITION
-- 会话/事务级
-- 自动清理
4.2 GTT 不变
CREATE GLOBAL TEMPORARY TABLE gtt_emp (...)
ON COMMIT DELETE ROWS;
5. Invisible Columns
CREATE TABLE employees (
id NUMBER,
name VARCHAR2(100),
salary NUMBER INVISIBLE
);
-- 默认不可见
DESC employees; -- 不显示 salary
-- 显式查询
SELECT id, name, salary FROM employees;
-- 修改
ALTER TABLE employees MODIFY salary VISIBLE;
ALTER TABLE employees MODIFY salary INVISIBLE;
6. Default 列
6.1 DEFAULT
CREATE TABLE employees (
id NUMBER,
name VARCHAR2(100),
status VARCHAR2(20) DEFAULT 'ACTIVE',
created_at TIMESTAMP DEFAULT SYSTIMESTAMP
);
6.2 序列
CREATE TABLE employees (
id NUMBER DEFAULT seq_emp.NEXTVAL PRIMARY KEY,
name VARCHAR2(100)
);
6.3 NULL
CREATE TABLE employees (
id NUMBER,
name VARCHAR2(100) DEFAULT ON NULL 'Unknown'
);
-- INSERT NULL 时使用默认值
7. MATCH_RECOGNIZE
SELECT *
FROM stock_prices
MATCH_RECOGNIZE (
PARTITION BY symbol
ORDER BY price_date
MEASURES
FINAL FIRST(up.price_date) AS start_date,
FINAL LAST(down.price_date) AS end_date
ONE ROW PER MATCH
PATTERN (up+ down+)
DEFINE
up AS up.price > PREV(up.price),
down AS down.price < PREV(down.price)
);
详细见:Oracle SQL 模式匹配。
8. LISTAGG 增强
8.1 DISTINCT
SELECT dept_id, LISTAGG(DISTINCT name, ',') WITHIN GROUP (ORDER BY name)
FROM employees
GROUP BY dept_id;
8.2 ON OVERFLOW
SELECT LISTAGG(name, ',' ON OVERFLOW TRUNCATE '...') WITHIN GROUP (ORDER BY name)
FROM employees;
9. JSON 支持
9.1 查询
SELECT JSON_VALUE(doc, '$.name'),
JSON_QUERY(doc, '$.skills')
FROM documents
WHERE JSON_EXISTS(doc, '$.salary > 5000');
9.2 JSON_TABLE
SELECT t.name, t.skill
FROM documents d,
JSON_TABLE(doc, '$'
COLUMNS (
name VARCHAR2(100) PATH '$.name',
NESTED PATH '$.skills[*]'
COLUMNS (skill VARCHAR2(50) PATH '$')
)
) t;
详细见:Oracle JSON 处理详解。
10. PL/SQL 增强
10.1 ACCESSIBLE BY
CREATE OR REPLACE PACKAGE emp_pkg
ACCESSIBLE BY (PROCEDURE hr_proc)
AS
...
END;
/
10.2 UTL_CALL_STACK
DECLARE
v_depth NUMBER;
BEGIN
v_depth := UTL_CALL_STACK.DYNAMIC_DEPTH;
FOR i IN 1..v_depth LOOP
DBMS_OUTPUT.PUT_LINE(
UTL_CALL_STACK.CONCATENATED_OWNER_NAME(i) || '.' ||
UTL_CALL_STACK.CONCATENATED_NAME(i)
);
END LOOP;
END;
/
10.3 DBMS_HPROF
EXEC DBMS_HPROF.START_PROFILING('HPROF_DIR', 'test.txt');
-- 执行
EXEC DBMS_HPROF.STOP_PROFILING;
11. 数据类型
11.1 VARCHAR2 32767
ALTER SYSTEM SET max_string_size = EXTENDED SCOPE = SPFILE;
-- 重启
@?/rdbms/admin/utl32k.sql
-- 32K 字符串
CREATE TABLE t (long_text VARCHAR2(32767));
11.2 PL/SQL
-- PL/SQL 32K
DECLARE
v_text VARCHAR2(32767);
BEGIN
...
END;
12. 临时表 Undo
CREATE TEMPORARY TABLE temp_sales (...)
ON COMMIT DELETE ROWS;
-- 12c+ 临时表 Undo 优化
13. 在线操作
13.1 MOVE ONLINE
ALTER TABLE employees MOVE ONLINE;
ALTER TABLE employees MOVE PARTITION p2024 ONLINE;
13.2 SPLIT ONLINE
ALTER TABLE sales SPLIT PARTITION pmax AT (...) ONLINE;
13.3 UPDATE INDEXES
ALTER TABLE sales MOVE PARTITION p2024 ONLINE UPDATE INDEXES;
14. Partial Index
CREATE TABLE sales (
id NUMBER,
sale_date DATE,
status VARCHAR2(10),
INDEXING OFF
)
PARTITION BY RANGE (sale_date) (
PARTITION p2024 ... INDEXING OFF,
PARTITION p2025 ... INDEXING ON
);
CREATE INDEX idx_sales_status ON sales(status) LOCAL INDEXING PARTIAL;
15. 多列外键 NULL
-- 12c+ 任一列 NULL 视为 NULL
ALTER TABLE child ADD CONSTRAINT fk_comp
FOREIGN KEY (a, b) REFERENCES parent(a, b) NULL; -- 默认
ALTER TABLE child ADD CONSTRAINT fk_comp
FOREIGN KEY (a, b) REFERENCES parent(a, b) NOT NULL;
16. 字段默认序列
-- 序列作为默认值
CREATE TABLE employees (
id NUMBER DEFAULT seq_emp.NEXTVAL PRIMARY KEY
);
17. Top N
-- FETCH
SELECT * FROM employees ORDER BY salary DESC
FETCH FIRST 10 ROWS ONLY;
18. 应用场景
18.1 分页
-- Web 分页
SELECT * FROM products
ORDER BY id
OFFSET :offset ROWS FETCH NEXT :limit ROWS ONLY;
18.2 自增 ID
-- 现代主键
CREATE TABLE t (
id NUMBER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
...
);
18.3 模式匹配
-- 金融分析
SELECT * FROM stock
MATCH_RECOGNIZE (...);
18.4 JSON
-- 半结构化
CREATE TABLE docs (doc JSON);
19. 性能
19.1 FETCH
- 比 ROWNUM 快
- 键集更快
19.2 IDENTITY
- 序列底层
- CACHE
19.3 临时表
- 私有临时表
- 内存
- 自动清理
20. 常见坑与排错
20.1 FETCH 性能
- 大 OFFSET 慢
- 键集替代
20.2 IDENTITY
- ALWAYS 不可指定
- BY DEFAULT 可指定
20.3 Invisible
- DESC 不显示
- 显式查询
21. 最佳实践
- FETCH:分页
- IDENTITY:主键
- Private Temp:临时
- Invisible:敏感
- MATCH_RECOGNIZE:模式
- JSON:半结构
- 32K:长字符串
- 在线操作:业务
- Partial Index:选择性
- 测试:兼容
22. 参考资料
[1] Oracle Database New Features Guide 12c https://docs.oracle.com/en/database/oracle/oracle-database/12.2/newft/