表值构造函数(Table Values Constructor) 是 Oracle 数据库 23ai 引入的一项新特性,它允许我们在 SQL 语句中通过单一构造表达式一次性定义多行数据。其实这种功能在其它数据库系统中(例如 MySQL)早就支持,MySQL 多行插入语法已经存在多年。
Oracle 通过在 23ai 中引入这一特性,它不仅能够减少网络往返次数、提高事务处理效率,而且还能使 SQL 语句更加直观、易于维护。无论是在数据导入、临时数据处理还是复杂数据同步场景中,这种简洁而强大的构造方式都能带来显著优势,帮助开发人员构建更高效、可靠的数据库应用。
在开始示例操作前,需要准备一张用于演示的表。本文中使用的表包含三个字段:
drop table if exists t1;
create table t1 (
id number,
code varchar2(6),
description varchar(25),
constraint t1_pk primary key (id)
);
使用表值构造函数,我们可以在单个 INSERT
语句中插入多条记录,而无需将多个独立的 INSERT
语句组合在一起。这样不仅可以减少网络往返的次数,还能在事务中一次性提交所有数据。
insert into t1
values (1, 'ONE', 'Description for ONE'),
(2, 'TWO', 'Description for TWO'),
(3, 'THREE', 'Description for THREE');
commit;
select * from t1;
ID CODE DESCRIPTION
---------- ------ -------------------------
1 ONE Description for ONE
2 TWO Description for TWO
3 THREE Description for THREE
表值构造函数同样可以用于 SELECT
语句的 FROM
子句中,直接构造一个临时数据集合用于查询或调试,这种方式为数据分析和快速测试提供了极大便利。
select *
from (values
(4, 'FOUR', 'Description for FOUR'),
(5, 'FIVE', 'Description for FIVE'),
(6, 'SIX', 'Description for SIX')
) a (id, code, description);
ID CODE DESCRIPTION
---------- ---- --------------------
4 FOUR Description for FOUR
5 FIVE Description for FIVE
6 SIX Description for SIX
将表值构造函数与 WITH 子句结合使用,可以创建公用表表达式(CTE),在后续的 SQL 查询中重复引用这一临时数据集,提高代码的模块化和可读性。
with a (id, code, description) AS (
values (7, 'SEVEN', 'Description for SEVEN'),
(8, 'EIGHT', 'Description for EIGHT'),
(9, 'NINE', 'Description for NINE')
)
select * from a;
ID CODE DESCRIPTION
---------- ----- ---------------------
7 SEVEN Description for SEVEN
8 EIGHT Description for EIGHT
9 NINE Description for NINE
表值构造函数也可以作为 MERGE 语句的数据源,实现数据的更新和插入(合并)操作。当源数据中的记录在目标表中存在时,执行更新操作;如果不存在,则执行插入操作,从而简化了数据同步与批处理任务。
merge into t1 a
using (values
(4, 'FOUR', 'Description for FOUR'),
(5, 'FIVE', 'Description for FIVE'),
(6, 'SIX', 'Description for SIX')
) b (id, code, description)
on (a.id = b.id)
when matched then
update set a.code = b.code,
a.description = b.description
when not matched then
insert (a.id, a.code, a.description)
values (b.id, b.code, b.description);
select * from t1;
ID CODE DESCRIPTION
---------- ------ -------------------------
1 ONE Description for ONE
2 TWO Description for TWO
3 THREE Description for THREE
4 FOUR Description for FOUR
5 FIVE Description for FIVE
6 SIX Description for SIX
采用表值构造函数带来了许多明显的好处,包括但不限于以下几点: