游乐游手机版
首页/数据库/文章详情

新版Oracle 26ai数据库SQL语言增强特性深度解析与应用

时间:2026-06-13 06:56
1 GROUP BY ALL 语法 首先介绍一项能够显著减轻手动编写负担的新特性:GROUP BY ALL。它的功能非常直接——自动将 SELECT 列表中的全部非聚合列作为分组依据,您完全无需逐一列出。这一特性在新项目开发中尤为实用,有效避免了重复复制列名的繁琐操作。 -- 传统写法:需要显式列

1. GROUP BY ALL 语法

首先介绍一项能够显著减轻手动编写负担的新特性:GROUP BY ALL。它的功能非常直接——自动将 SELECT 列表中的全部非聚合列作为分组依据,您完全无需逐一列出。这一特性在新项目开发中尤为实用,有效避免了重复复制列名的繁琐操作。

Oracle 26ai的SQL语言增强特性

-- 传统写法:需要显式列出所有非聚合列
SELECT department_id, job_id, A VG(salary) AS a vg_sal
FROM employees
GROUP BY department_id, job_id;

-- 26ai 新写法:使用 GROUP BY ALL 自动包含所有非聚合列
SELECT department_id, job_id, A VG(salary) AS a vg_sal
FROM employees
GROUP BY ALL;

适用场景非常明确:当您的 SELECT 列表中包含大量列时,传统的 GROUP BY 写法很容易遗漏某个列导致语法错误,此时 GROUP BY ALL 就能发挥关键作用,成为效率救星。

2. QUALIFY 子句(窗口函数过滤)

窗口函数虽然功能强大,但之前想要过滤其结果必须嵌套子查询或 CTE,代码结构像是层层叠罗汉。现在借助 QUALIFY,只需在末尾添加一行即可干净利落地完成过滤。

-- 传统写法:需要子查询或 CTE
WITH ranked AS (
    SELECT employee_id, first_name, salary,
           RANK() OVER (ORDER BY salary DESC) AS salary_rank
    FROM employees
)
SELECT * FROM ranked WHERE salary_rank <= 5;

-- 26ai 新写法:使用 QUALIFY 直接过滤
SELECT employee_id, first_name, salary,
       RANK() OVER (ORDER BY salary DESC) AS salary_rank
FROM employees
QUALIFY salary_rank <= 5;

-- 另一个示例:查找每个部门工资前 3 的员工
SELECT department_id, first_name, salary,
       ROW_NUMBER() OVER (PARTITION BY department_id ORDER BY salary DESC) AS rn
FROM employees
QUALIFY rn <= 3;

3. UUID() 函数(RFC 9562 版本 4)

生成 UUID 如今不再需要手动拼接或调用第三方函数。UUID() 可以直接输出符合 RFC 9562 版本 4 标准的 UUID,使用起来如同 SYSDATE 一样直观自然。

-- 生成单个 UUID
SELECT UUID() FROM dual;
-- 结果示例:550e8400-e29b-41d4-a716-446655440000

-- 插入数据时自动生成 UUID
CREATE TABLE users (
    user_id RAW(16) DEFAULT UUID() PRIMARY KEY,
    username VARCHAR2(50),
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
INSERT INTO users (username) VALUES ('zhangsan');
-- user_id 自动填充为 UUID

-- 批量生成 UUID
SELECT UUID() AS id, first_name FROM employees WHERE department_id = 10;

4. GROUP BY 支持列别名或位置编号

以前 GROUP BY 必须使用原始列名或完整表达式,写法冗长。现在 Oracle 终于允许通过 SELECT 中的别名或位置编号直接分组,代码瞬间变得简洁清爽。

-- 传统写法:重复表达式或使用列名
SELECT SUBSTR(hire_date, 1, 4) AS hire_year, COUNT(*) AS cnt
FROM employees
GROUP BY SUBSTR(hire_date, 1, 4);

-- 26ai 新写法:使用列别名
SELECT SUBSTR(hire_date, 1, 4) AS hire_year, COUNT(*) AS cnt
FROM employees
GROUP BY hire_year;

-- 使用位置编号(从 1 开始)
SELECT department_id, job_id, A VG(salary) AS a vg_sal
FROM employees
GROUP BY 1, 2;  -- 按第 1 列(department_id)和第 2 列(job_id)分组

-- 混合使用别名和位置编号
SELECT department_id, job_id, A VG(salary) AS a vg_sal
FROM employees
GROUP BY 1, job_id;  -- 位置 1 和别名混用

5. 非位置 INSERT 子句(命名列插入)

传统的 INSERT 语句要求值的顺序必须与表定义完全一致,当列数较多时极易出错。新引入的命名列插入允许使用 列名 => 值 的语法,顺序完全自由,代码可读性显著提升。

-- 传统写法:必须按列定义顺序,VALUES 顺序必须与列列表一致
INSERT INTO employees (employee_id, first_name, last_name, email, hire_date, job_id)
VALUES (207, 'John', 'Smith', 'jsmith', SYSDATE, 'IT_PROG');

-- 26ai 新写法:命名列插入,可以任意顺序指定
INSERT INTO employees (
    employee_id => 207,
    last_name => 'Smith',
    first_name => 'John',
    job_id => 'IT_PROG',
    email => 'jsmith',
    hire_date => SYSDATE
);

-- 批量插入时更清晰
INSERT ALL
    INTO employees (employee_id => 208, last_name => 'Wang', first_name => 'Wei', job_id => 'SA_REP')
    INTO employees (employee_id => 209, first_name => 'Li', last_name => 'Hua', job_id => 'MK_MAN')
SELECT 1 FROM dual;
来源:https://www.jb51.net/database/361853htu.htm
上一篇MySQL Redo Log落盘机制的核心原理与完整流程深度解析 下一篇Oracle不同权限下查询表视图字段的SQL整理方法
本站内容用于信息整理与展示,如有侵权或内容问题请及时联系处理。

相关推荐

补充同频道和同主题内容,方便继续浏览更多相关内容。

同类最新

继续查看同栏目最近更新的文章。

更多
Redis 7.0增量AOF重写RDB前导码配置详解
数据库 · 2026-07-02

Redis 7.0增量AOF重写RDB前导码配置详解

先说一个几乎所有人都踩过的典型误区:很多人把 aof-use-rdb-preamble yes 当作开启“增量重写”的开关。实际上,这个配置只干了一件事——让重写后的 AOF 文件头部带上 RDB 快照。它解决的是加载速度问题,跟“增量重写”本身的概念压根不是一回事。真正的增量重写,依赖的是 Red

在Python Tornado异步框架中安全执行SQL命令的方法与最佳实践
数据库 · 2026-07-02

在Python Tornado异步框架中安全执行SQL命令的方法与最佳实践

直接在Tornado里用SQLAlchemy同步执行SQL,结果就是阻塞IOLoop,所谓“异步框架里写同步数据库代码”,等于白搭。安全执行的关键不是“怎么写SQL”,而是“怎么不卡住事件循环”。 为什么不能在RequestHandler里直接调用session execute() 因为sessio

利用SQL触发器实现在INSERT数据时自动同步到审计表
数据库 · 2026-07-02

利用SQL触发器实现在INSERT数据时自动同步到审计表

先说结论:可以用触发器把 INSERT 数据同步到审计表,但必须用 AFTER INSERT,并且审计表的字段顺序、类型、字符集得和源表严格一致。否则,轻则写入错位、数据截断,重则直接报错、丢数据。下面把这些坑一个一个掰开说。 能,但必须用 AFTER INSERT,且审计表字段顺序、类型、字符集要

如何用SQL编写按不同工作日统计员工出勤率
数据库 · 2026-07-02

如何用SQL编写按不同工作日统计员工出勤率

在实际业务中,统计不同工作日的出勤率是HR系统里的高频需求。如果直接按日期函数分组,很容易掉进语言环境、索引失效或分母口径的坑里。下面就来拆解具体的实现要点。 必须用 CASE WHEN 将日期映射为固定 weekday 标签(如 Mon )再分组,避免语言环境导致的分组断裂;需过滤 DOW IN

Spring Boot 3动态拼接SQL为何引发严重安全漏洞
数据库 · 2026-07-02

Spring Boot 3动态拼接SQL为何引发严重安全漏洞

SQL注入漏洞的核心成因,本质上是因为用户输入直接参与了SQL语句的字符串拼接,而未采用参数化绑定机制。在MyBatis中使用${}、QueryWrapper中调用apply()与last()、JPA的@Query注解进行拼接等操作,都会绕过PreparedStatement的安全防护。动态字段必须