首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >26ai新特性实战:JSON关系二元性验证指令

26ai新特性实战:JSON关系二元性验证指令

作者头像
胖头鱼的鱼缸
发布2026-07-16 20:11:24
发布2026-07-16 20:11:24
550
举报

胖头鱼的技术专栏-447 26ai新特性实战:JSON关系二元性验证指令(20260716)

代码语言:javascript
复制
作者:胖头鱼的鱼缸(尹海文)
Oracle ACE Pro: Database
PostgreSQL ACE

10年+数据库行业经验
拥有OCM 11g/12c/19c、MySQL 8.0 OCP、Exadata、CDP等认证
墨天轮MVP,ITPUB认证专家
圈内拥有“总监”称号,非著名社恐(社交恐怖分子)

全网同名:胖头鱼的鱼缸
ITPUB:yhw1809
除授权转载并标明出处外,均为“非法”抄袭
914fcc7ad57defa7868c3be1ca7fb4f5.jpg
914fcc7ad57defa7868c3be1ca7fb4f5.jpg

特性介绍

Oracle AI Database 23.26.2为JSON关系二元性视图新增了验证指令(Validation Directive)功能。验证指令允许开发者以声明式的方式为Duality View 及其底层表附加补充的业务规则逻辑。

验证逻辑存储在数据库中,在对Duality View执行操作(插入、更新、查询)时自动评估执行。这为传统的应用代码或数据库触发器实现业务规则提供了一种声明式的替代方案。

语法介绍

代码语言:javascript
复制
CREATE [ORREPLACE] DIRECTIVE 指令名称
FOR Duality_View 名称
VALIDATE
ON ( SELECT | INSERT | UPDATE )+    -- 可指定一个或多个操作
  ( BEFOREOBJECT | AFTEROBJECT | ONCOMMIT )  -- 处理阶段
  [ (VALIDATE | NOVALIDATE) (ENABLE | DISABLE) ]  -- 可选
USING ( SQL表达式 | PLSQL函数 );

处理阶段(Processing Stage):

  • BEFORE OBJECT - 在文档处理之前验证,失败则操作不执行,语句回滚
  • AFTER OBJECT - 在文档处理之后验证,失败则回滚语句并报错
  • ON COMMIT - 在事务提交时验证,失败则提交被拒绝,事务回滚(提供更强的事务一致性保证)

验证失败行为:

  • SELECT验证失败 - 抛出错误,不返回验证失败的文档
  • INSERT/UPDATE验证失败 - 操作被拒绝,语句回滚
  • ON COMMIT验证失败 - 提交失败,整个事务回滚

验证逻辑支持三种形式:

  1. SQL/JSON表达式:如 json_value(new.data, ‘$.salary’) < 10000
  2. PL/SQL函数:函数签名为 (old_data JSON, new_data JSON) RETURN BOOLEAN
    • new_data:插入/更新后的文档(提议版本)
    • old_data:更新前的文档(原始版本,INSERT 时为 null)
    • 返回 TRUE 表示验证通过,FALSE 表示验证失败
  3. PL/SQL匿名块

VALIDATE/NOVALIDATE 选项:

  • VALIDATE - 创建指令时验证现有数据(如有不合规数据,创建失败)
  • NOVALIDATE - 创建指令时不验证现有数据(默认)

ENABLE/DISABLE 选项:

  • ENABLE - 创建后立即生效(默认)
  • DISABLE - 创建后不生效(可用 ALTER DIRECTIVE 启用)

错误码:

  • ORA-43589: Cannot create validation directive ‘xxxx’: Validation directives creation is not supported under the SYS schema (不能在SYS schema下创建验证指令,使用SYS用户登录切换至其他SCHEMA也会报错)
  • OORA-43591: Validation failed for directive ‘xxxx’ on JSON-relational duality view ‘xxxx’ (验证失败)

限制

  • 不能在 SYS schema 下创建验证指令
  • 验证逻辑必须确定性且无副作用
  • 禁止 DML、ALTER SESSION、COMMIT/ROLLBACK、PRAGMA AUTONOMOUS_TRANSACTION
  • 禁止修改包状态,禁止使用 UTL_HTTP、UTL_TCP、UTL_SMTP 等包
  • 存在验证指令时,并行 DML 和直接加载操作会降级为串行常规 DML

适用场景

  • 业务规则强制执行:例如确保员工薪资在合理范围内(2000 ≤ salary < 10000)
  • 订单状态保护:已发货订单(status = ‘shipped’)不允许添加新的订单项,使用 ON COMMIT 阶段防止并发修改
  • 数据质量管控:查询时验证文档完整性,不返回不符合规则的文档
  • 合规审计:确保插入的文档满足行业合规要求,如金融交易必须包含必要字段
  • 多租户隔离:验证租户不能访问或修改其他租户的数据
  • 替代触发器:将原本在应用层或触发器中实现的验证逻辑下沉到数据库声明式管理

实战演示

创建测试表和视图

代码语言:javascript
复制
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);
image.png
image.png

测试1:使用SQL表达式对INSERT(BEFORE OBJECT)验证

代码语言:javascript
复制
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"}');
image.png
image.png

salary≥10000的无法被插入。

测试2:使用PL/SQL函数对INSERT(BEFORE OBJECT)验证

代码语言:javascript
复制
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"}');
image.png
image.png

salary≥2000的才能被插入。

测试3:UPDATE验证(BEFORE OBJECT)

代码语言:javascript
复制
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;
image.png
image.png

修改salary≥10000会失败。

测试4:SELECT验证(AFTER OBJECT)

代码语言:javascript
复制
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);
image.png
image.png

查询完整数据,对于TEST文档失败。查询单个字段应成功(无SELECT验证)。

查询所有验证指令

代码语言:javascript
复制
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;
image.png
image.png

总结

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

老规矩,知道写了些啥。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2026-07-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 胖头鱼的鱼缸 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 胖头鱼的技术专栏-447 26ai新特性实战:JSON关系二元性验证指令(20260716)
    • 特性介绍
    • 语法介绍
    • 限制
    • 适用场景
    • 实战演示
      • 创建测试表和视图
      • 测试1:使用SQL表达式对INSERT(BEFORE OBJECT)验证
      • 测试2:使用PL/SQL函数对INSERT(BEFORE OBJECT)验证
      • 测试3:UPDATE验证(BEFORE OBJECT)
      • 测试4:SELECT验证(AFTER OBJECT)
      • 查询所有验证指令
    • 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档