如何在SQL存储过程中安全解析JSON格式入参

陌墨吖_3918

陌墨吖_3918

2026-11-01

335人浏览

原创

所有数据库解析JSON前必须校验结构合法性,否则解析失败即硬错误;SQL Server需WITH子句映射类型,PostgreSQL要求jsonb_to_record完全匹配,MySQL需显式转换类型,Oracle须用JSON_VALID前置校验。

如何在sql存储过程中安全解析json格式入参

SQL Server里用OPENJSON解析JSON参数必须加WITH子句

不加WITH直接SELECT * FROM OPENJSON(@json)只能拿到键名和原始值,没法映射成带类型、可参与计算的列。尤其当JSON里有嵌套对象或数组时,缺WITH会导致后续JOIN或WHERE失效。

实操建议:

  • WITH里每个字段必须显式声明类型,比如name NVARCHAR(50),不能只写name
  • 路径表达式要用'$.field'格式,注意单引号包裹,双引号会报错
  • 如果JSON字段可能为null,类型后面加NULL(如status TINYINT NULL),否则遇到空值直接中断解析
  • 嵌套对象用JSON_QUERY('$.items')提取字符串,再套一层OPENJSON处理,别试图在一级WITH里展开多层

PostgreSQL中jsonb_to_record()要求输入严格匹配字段定义

jsonb_to_record()不是“尽力而为”,而是“完全匹配”。传入JSON里多一个字段、少一个字段、类型对不上,都会抛ERROR: record type does not match supplied data。

常见错误现象:

  • 前端传了{"user_id": "123", "tags": ["a","b"]},但函数定义里写了tags TEXT[]——看着一样,实际"123"是字符串,123才是整数,类型不匹配就崩
  • 用jsonb_populate_record()时没给默认值,JSON缺字段就报错,而不是填NULL
  • 字段名大小写敏感:JSON里是userId,函数定义写userid,直接不识别

安全做法是先用jsonb_typeof()校验关键字段类型,再进主逻辑;或者改用jsonb_path_query()配合COALESCE做兜底。

MySQL 8.0+的JSON_EXTRACT()返回的是JSON字符串,不是原生类型

JSON_EXTRACT(@json, '$.price')结果是"199.00"(带双引号),不是数值199.00。直接拿它参与WHERE price > 100会隐式转成字符串比较,导致逻辑错乱。

Expanso json-flatten
Expanso json-flatten

通过 CLI 或 MCP 服务器,使用 Expanso Edge 管道扁平化嵌套 JSON 对象。

下载

正确解法只有两个:

  • 用CAST(JSON_EXTRACT(@json, '$.price') AS DECIMAL(10,2))显式转类型
  • 用JSON_UNQUOTE(JSON_EXTRACT(@json, '$.price'))去掉引号后再转,否则CAST对带引号字符串无效
  • 数组字段如$.tags不能直接IN,得先JSON_TABLE()展开成行集
  • 别信->操作符能省事——@json->'$.price'和JSON_EXTRACT()行为一致,同样要处理引号

Oracle存储过程中解析JSON需提前检查JSON_VALID(),否则ORA-40441必现

Oracle 12c+虽支持JSON_VALUE(),但只要输入不是合法JSON,哪怕只是多一个逗号、少一个括号,就会立刻抛ORA-40441: JSON syntax error,且无法被EXCEPTION块捕获——它属于编译期错误,不是运行时异常。

所以必须前置校验:

  • 调用JSON_VALID(@json) = 'TRUE',返回FALSE就直接RETURN或抛自定义异常
  • JSON_VALUE()的路径参数必须是字符串字面量,不能拼接变量,否则编译失败
  • 取嵌套值如$.data.items[0].name,索引越界不会报错,而是返回NULL,这点和PostgreSQL不同
  • 如果JSON含Unicode转义(如\u4f60),确保数据库字符集是AL32UTF8,否则解析后变乱码

真正难的不是语法怎么写,而是所有数据库都把“JSON解析失败”当作硬错误而非可恢复异常——这意味着你得在进存储过程第一行就做完结构校验,而不是等执行到中间才崩。漏掉这步,线上就等着收告警。

相关文章

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

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

下载

相关标签:

js json 存储过程

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系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

4663

8

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

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

2023.10.27

971

4

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

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

2024.02.23

1229

5

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

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

2024.03.06

6661

10

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

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

2024.03.06

3403

4

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

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

2024.04.07

6640

11

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

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

2024.04.29

9161

6

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

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

2024.04.29

1230

5

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

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

2024.04.29

1092

5

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
WEB前端教程【HTML5+CSS3+JS】
WEB前端教程【HTML5+CSS3+JS】

共101课时 | 21.3万人学习

JS进阶与BootStrap学习
JS进阶与BootStrap学习

共39课时 | 4.9万人学习