如何在Oracle 21c中利用触发器实现JSON文档字段的自动验证?

老伟君_6183

老伟君_6183

2026-07-24

484人浏览

原创

oracle 21c json列需用触发器验证:先用is json = 0判语法合法性,再用json_value(... error on error)校验业务规则;自动补全用json_merge_patch;嵌套数组校验宜移至应用层。

如何在oracle 21c中利用触发器实现json文档字段的自动验证?

Oracle 21c 的 JSON 数据类型本身不支持列级约束(比如 CHECK (json_data IS JSON) 在 21c 中虽可用,但无法捕获结构或业务逻辑错误),所以必须靠触发器补位。直接在 INSERT 或 UPDATE 时验证,比事后查错更可靠。

触发器里怎么判断字段是合法 JSON?用 IS JSON 而不是 JSON_EXISTS

IS JSON 是唯一能确认字符串是否为语法合法 JSON 的内置条件,它返回 1 或 0(不是布尔值,注意类型)。JSON_EXISTS 前提是输入已为合法 JSON,若传入乱码会直接报错(如 ORA-40442: JSON syntax error),导致触发器中断,反而绕过验证。

  • 必须写成 IF json_col IS JSON = 0 THEN RAISE_APPLICATION_ERROR(...); END IF;
  • 不能写成 IF NOT JSON_EXISTS(json_col, '$') THEN ... —— 这会在非法 JSON 上抛异常,无法进入 THEN 分支
  • 如果字段允许为 NULL,需额外判断:json_col IS NULL OR json_col IS JSON = 1

业务规则验证得用 JSON_VALUE + 异常捕获,别硬套 CHECK

比如要求 $.status 必须是 'active' 或 'inactive',且 $.created_at 必须是 ISO 格式时间。这类逻辑无法用单个 SQL 条件表达,必须在 PL/SQL 块中调用 JSON_VALUE 并捕获 VALUE_ERROR 或检查返回值:

chartjs-reporter
chartjs-reporter

此技能用于在用户需要将结构化数据(查询结果、CSV 摘要、JSON 记录或 Python 字典/列表)转换为独立的 HTML 页面时使用。

下载
  • JSON_VALUE(json_col, '$.status' RETURNING VARCHAR2(20)) 若路径不存在会返回 NULL,不是报错;若想强制存在,加 ERROR ON ERROR
  • 写法示例:l_status := JSON_VALUE(json_col, '$.status' ERROR ON ERROR); IF l_status NOT IN ('active', 'inactive') THEN ...
  • 时间字段验证建议先用 JSON_VALUE(... RETURNING TIMESTAMP),成功则说明格式可转,再加业务逻辑判断(如不能晚于当前时间)

触发器里修改 JSON 内容?别碰 JSON_TRANSFORM,用 JSON_MERGE_PATCH 更安全

有些场景需要“自动补全缺失字段”,比如插入时没给 $.version 就默认设为 1。这时不要在触发器里用 JSON_TRANSFORM(它语法复杂、易写错路径,且对空对象处理不直观),改用 JSON_MERGE_PATCH:

  • NEW.json_data := JSON_MERGE_PATCH(NEW.json_data, '{"version": 1}'); —— 自动合并,不覆盖已有字段
  • 如果原值是 NULL,JSON_MERGE_PATCH(NULL, '{...}') 返回 {...},行为可预期
  • 避免用字符串拼接(如 '{"version":1,' || json_col || '}'),极易因引号或转义出错
  • 注意:触发器中赋值必须用 :NEW.json_data(行级触发器),且表定义中该列为 JSON 类型,否则隐式转换可能失败

真正难的是嵌套数组的业务校验——比如 $.items[*].price 每一项都必须 > 0。这必须用 JSON_TABLE 展开后查,但触发器里执行 DML 式查询开销大,还可能引发 mutating table 错误。这种逻辑更适合移到应用层或用物化视图+约束组合实现,别硬塞进触发器。

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
数据分析工具有哪些
数据分析工具有哪些

数据分析工具有Excel、SQL、Python、R、Tableau、Power BI、SAS、SPSS和MATLAB等。详细介绍:1、Excel,具有强大的计算和数据处理功能;2、SQL,可以进行数据查询、过滤、排序、聚合等操作;3、Python,拥有丰富的数据分析库;4、R,拥有丰富的统计分析库和图形库;5、Tableau,提供了直观易用的用户界面等等。

2023.10.12

4483

8

SQL中distinct的用法
SQL中distinct的用法

SQL中distinct的语法是“SELECT DISTINCT column1, column2,...,FROM table_name;”。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2023.10.27

931

4

SQL中months_between使用方法
SQL中months_between使用方法

在SQL中,MONTHS_BETWEEN 是一个常见的函数,用于计算两个日期之间的月份差。想了解更多SQL的相关内容,可以阅读本专题下面的文章。

2024.02.23

1169

5

SQL出现5120错误解决方法
SQL出现5120错误解决方法

SQL Server错误5120是由于没有足够的权限来访问或操作指定的数据库或文件引起的。想了解更多sql错误的相关内容,可以阅读本专题下面的文章。

2024.03.06

6441

10

sql procedure语法错误解决方法
sql procedure语法错误解决方法

sql procedure语法错误解决办法:1、仔细检查错误消息;2、检查语法规则;3、检查括号和引号;4、检查变量和参数;5、检查关键字和函数;6、逐步调试;7、参考文档和示例。想了解更多语法错误的相关内容,可以阅读本专题下面的文章。

2024.03.06

3223

4

oracle数据库运行sql方法
oracle数据库运行sql方法

运行sql步骤包括:打开sql plus工具并连接到数据库。在提示符下输入sql语句。按enter键运行该语句。查看结果,错误消息或退出sql plus。想了解更多oracle数据库的相关内容,可以阅读本专题下面的文章。

2024.04.07

6400

11

sql中where的含义
sql中where的含义

sql中where子句用于从表中过滤数据,它基于指定条件选择特定的行。想了解更多where的相关内容,可以阅读本专题下面的文章。

2024.04.29

8761

6

sql中删除表的语句是什么
sql中删除表的语句是什么

sql中用于删除表的语句是drop table。语法为drop table table_name;该语句将永久删除指定表的表和数据。想了解更多sql的相关内容,可以阅读本专题下面的文章。

2024.04.29

1190

5

sql中删除一列的命令是什么
sql中删除一列的命令是什么

在sql中,使用alter table语句可以删除一列,语法为:alter table table_name drop column column_name。想了解更多sql的相关内容,可以阅读本专题下面的文章。

2024.04.29

1032

5

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程