
作者:胖头鱼的鱼缸(尹海文)
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关系二元性视图新增了验证指令(Validation Directive)功能。验证指令允许开发者以声明式的方式为Duality View 及其底层表附加补充的业务规则逻辑。
验证逻辑存储在数据库中,在对Duality View执行操作(插入、更新、查询)时自动评估执行。这为传统的应用代码或数据库触发器实现业务规则提供了一种声明式的替代方案。
CREATE [ORREPLACE] DIRECTIVE 指令名称
FOR Duality_View 名称
VALIDATE
ON ( SELECT | INSERT | UPDATE )+ -- 可指定一个或多个操作
( BEFOREOBJECT | AFTEROBJECT | ONCOMMIT ) -- 处理阶段
[ (VALIDATE | NOVALIDATE) (ENABLE | DISABLE) ] -- 可选
USING ( SQL表达式 | PLSQL函数 );
处理阶段(Processing Stage):
验证失败行为:
验证逻辑支持三种形式:
VALIDATE/NOVALIDATE 选项:
ENABLE/DISABLE 选项:
错误码:
CREATE TABLE vd_employees (
emp_id NUMBER PRIMARY KEY,
emp_name VARCHAR2(100),
salary NUMBER,
dept VARCHAR2(30)
);
CREATE OR REPLACE JSON RELATIONAL DUALITY VIEW vd_emp_dv AS
SELECT JSON {'_id' : emp_id,
'name' : emp_name,
'salary': salary,
'dept' : dept}
FROM vd_employees WITH (INSERT, UPDATE, DELETE);

CREATE DIRECTIVE salary_max_check FOR vd_emp_dv
VALIDATE
ON INSERT
BEFORE OBJECT
USING json_value(new.data, '$.salary') < 10000;
INSERT INTO vd_emp_dv VALUES ('{"_id":1, "name":"Alice", "salary":5000, "dept":"Engineering"}');
INSERT INTO vd_emp_dv VALUES ('{"_id":2, "name":"Bob", "salary":15000, "dept":"Sales"}');

salary≥10000的无法被插入。
CREATE OR REPLACE FUNCTION check_min_salary(old_data JSON, new_data JSON)
RETURN BOOLEAN
IS
BEGIN
RETURN json_value(new_data, '$.salary') >= 2000;
END;
/
CREATE DIRECTIVE salary_min_check FOR vd_emp_dv
VALIDATE
ON INSERT
BEFORE OBJECT
NOVALIDATE
USING check_min_salary;
INSERT INTO vd_emp_dv VALUES ('{"_id":3, "name":"Carol", "salary":3000, "dept":"HR"}');
INSERT INTO vd_emp_dv VALUES ('{"_id":4, "name":"Dave", "salary":1000, "dept":"Sales"}');

salary≥2000的才能被插入。
CREATE DIRECTIVE salary_update_check FOR vd_emp_dv
VALIDATE
ON UPDATE
BEFORE OBJECT
USING json_value(new.data, '$.salary') < 10000;
UPDATE vd_emp_dv SET data = JSON_TRANSFORM(data, SET'$.salary' = 8000)
WHERE JSON_VALUE(data, '$._id' RETURNING NUMBER) = 1;
UPDATE vd_emp_dv SET data = JSON_TRANSFORM(data, SET'$.salary' = 12000)
WHERE JSON_VALUE(data, '$._id' RETURNING NUMBER) = 1;

修改salary≥10000会失败。
CREATE OR REPLACE DIRECTIVE no_test_names FOR vd_emp_dv
VALIDATE
ON SELECT
AFTER OBJECT
NOVALIDATE ENABLE
USING json_value(new.data, '$.name') != 'TEST';
INSERT INTO vd_employees VALUES (5, 'TEST', 5000, 'Temp');
COMMIT;
SELECT data FROM vd_emp_dv WHERE JSON_VALUE(data, '$._id' RETURNING NUMBER) = 5;
SELECT JSON_VALUE(data, '$._id') AS id, JSON_VALUE(data, '$.name') AS name
FROM vd_emp_dv ORDER BY JSON_VALUE(data, '$._id' RETURNING NUMBER);

查询完整数据,对于TEST文档失败。查询单个字段应成功(无SELECT验证)。
SELECT directive_name, object_name, on_clause, processing_stage_clause, status, using_type
FROM user_validation_directives
WHERE object_name = 'VD_EMP_DV'
ORDER BY directive_name;

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