
作者:胖头鱼的鱼缸(尹海文)
Oracle ACE Pro: Database
PostgreSQL ACE
10年+数据库行业经验
拥有OCM 11g/12c/19c、MySQL 8.0 OCP、Exadata、CDP等认证
墨天轮MVP,ITPUB认证专家
圈内拥有“总监”称号,非著名社恐(社交恐怖分子)
全网同名:胖头鱼的鱼缸
ITPUB:yhw1809
除授权转载并标明出处外,均为“非法”抄袭

Oracle AI Database 23.26.2 引入了JSON Relational Duality View(JSON关系二元性视图)内联写增强(Inline Write Augmentation)功能。当通过 Duality View 插入或更新文档时,该功能可以自动创建输入文档中不存在的额外字段,并为其赋值。
这意味着开发者可以:
两种生成模式:
生成表达式支持:
SQL DDL:
'field': column GENERATED ON WRITE USING PATH 'expression'
'field': column GENERATED ON WRITE IF MISSING USING PATH 'expression'
还可与读增强(READ augmentation)组合使用,以及将字段设为 HIDDEN(不出现在返回的文档中,但值持久化到列)。
GraphQL:
field: column @generated(path: "expression", on: "write") -- 无条件
field: column @generated(path: "expression", on: "missing") -- 条件
field: column @generated(path: "expression", on: "write") @hidden
下面是一些可以使用该特性的实际生产业务场景:
同之前一样,使用用户NFTEST,已授权DB_DEVELOPER_ROLE角色,测试操作均在NFTEST用户下执行。
CREATE TABLE dva_employees (
emp_id NUMBER PRIMARY KEY,
emp_name VARCHAR2(100),
salary NUMBER,
bonus NUMBER,
dept_code VARCHAR2(10),
shift_pref JSON,
shift_prio VARCHAR2(50)
);

插入数据是“bonus”字段不指定值自动生成值500。
CREATE OR REPLACE JSON RELATIONAL DUALITY VIEW dva_emp_const AS
SELECT JSON {'_id' : emp_id,
'name' : emp_name,
'salary' : salary,
'bonus' : bonus GENERATEDON WRITE USING PATH '500'}
FROM dva_employees WITH (INSERT, UPDATE, DELETE);
INSERT INTO dva_emp_const VALUES ('{"_id":1, "name":"Alice", "salary":50000}');
SELECT data FROM dva_emp_const WHERE JSON_VALUE(data, '$._id' RETURNING NUMBER) = 1;
SELECT * FROM dva_employees;

bouns列均赋值500。
INSERT INTO dva_emp_const VALUES ('{"_id":2, "name":"Bob", "salary":60000, "bonus":1000}');

因为无条件的限制,无法在bonus字段有值时成功插入数据。
CREATE OR REPLACE JSON RELATIONAL DUALITY VIEW dva_emp_missing AS
SELECT JSON {'_id' : emp_id,
'name' : emp_name,
'salary' : salary,
'bonus' : bonus GENERATEDON WRITE IF MISSING USING PATH '500'}
FROM dva_employees WITH (INSERT, UPDATE, DELETE);
INSERT INTO dva_emp_missing VALUES ('{"_id":3, "name":"Carol", "salary":70000}');
INSERT INTO dva_emp_missing VALUES ('{"_id":4, "name":"Dave", "salary":80000, "bonus":2000}');
SELECT data FROM dva_emp_missing WHERE JSON_VALUE(data, '$._id' RETURNING NUMBER) IN (3, 4)
ORDER BY JSON_VALUE(data, '$._id' RETURNING NUMBER);

bonus字段指定与否都可以插入。
当salary>60000时,bonus为1000,否则为500。
CREATE OR REPLACE JSON RELATIONAL DUALITY VIEW dva_emp_case AS
SELECT JSON {'_id' : emp_id,
'name' : emp_name,
'salary' : salary,
'bonus' : bonus GENERATEDON WRITE USING PATH 'case(@.salary>60000,1000,500)'}
FROM dva_employees WITH (INSERT, UPDATE, DELETE);
INSERT INTO dva_emp_case VALUES ('{"_id":10, "name":"Eve", "salary":45000}');
INSERT INTO dva_emp_case VALUES ('{"_id":11, "name":"Frank", "salary":75000}');
SELECT data FROM dva_emp_case WHERE JSON_VALUE(data, '$._id' RETURNING NUMBER) IN (10, 11)
ORDER BY JSON_VALUE(data, '$._id' RETURNING NUMBER);

shiftPri是从shiftPref属组的第一个值派生
CREATE OR REPLACE JSON RELATIONAL DUALITY VIEW dva_emp_derived AS
SELECT JSON {'_id' : emp_id,
'name' : emp_name,
'salary' : salary,
'shiftPref' : shift_pref,
'shiftPrio' : shift_prio GENERATED ON WRITE USING PATH '$.shiftPref[0]'}
FROM dva_employees WITH (INSERT, UPDATE, DELETE);
INSERT INTO dva_emp_derived VALUES
('{"_id":20, "name":"Grace", "salary":90000, "shiftPref":["night","day","flex"]}');
SELECT data FROM dva_emp_derived WHERE JSON_VALUE(data, '$._id' RETURNING NUMBER) = 20;
-- 验证关系表中数据
SELECT emp_id, emp_name, shift_pref, shift_prio FROM dva_employees WHERE emp_id = 20;

本期对Oracle AI Database 26ai,23.26.2版本新引入的JSON关系二元性内联写增强新特性进行了完整介绍与实战演示。
老规矩,知道写了些啥。