如何在SQL中从HUGEBLOB转换的字符串提取ITEM编码
解决方案:从HUGEBLOB转换的JSON中提取ITEM编码
问题分析
你之前的正则表达式仅用[[:alpha:]_]+匹配ITEM后的内容,只能识别字母和下划线,无法覆盖数字开头或含数字的编码;而SUBSTR+INSTR的写法依赖ITEM在LOC之后的固定顺序,一旦顺序调换就失效。需要一种不依赖顺序、能匹配所有合法ITEM编码的方法。
方案1:修正正则表达式(通用兼容)
调整正则匹配规则,匹配ITEM:之后到下一个逗号或引号之间的所有字符(ITEM编码的结束标记要么是分隔用的逗号,要么是intersectionKey字段的闭合引号),同时兼容任意顺序的LOC/ITEM。
优化后的SQL
WITH audit_data AS ( SELECT auditid, UTL_RAW.CAST_TO_VARCHAR2(DBMS_LOB.substr(searchableattrib, 1000, 1)) AS json_str FROM auditlog WHERE auditid = '3622fe86-0db7-4c79-afb1-b7cdcc99c0e4' ) SELECT auditid, REGEXP_SUBSTR(json_str, 'ITEM:[[:space:]]*([^,"]+)', 1, 1, NULL, 1) AS item, json_str FROM audit_data;
正则说明
ITEM:[[:space:]]*:匹配ITEM:及后面的任意空格,兼容可能的空格差异([^,"]+):捕获组,匹配不是逗号和引号的所有字符,刚好对应ITEM编码的结束位置- 最后一个参数
1表示返回第一个捕获组的内容,直接得到ITEM编码
方案2:利用Oracle JSON函数(12c+版本推荐)
如果你的Oracle版本是12c及以上,可以直接用JSON解析函数先提取intersectionKey字段,再在该字段内提取ITEM编码,逻辑更清晰,也避免了整个JSON字符串中其他内容的干扰。
SQL示例
WITH audit_data AS ( SELECT auditid, UTL_RAW.CAST_TO_VARCHAR2(DBMS_LOB.substr(searchableattrib, 1000, 1)) AS json_str FROM auditlog WHERE auditid = '3622fe86-0db7-4c79-afb1-b7cdcc99c0e4' ) SELECT auditid, REGEXP_SUBSTR( JSON_VALUE(json_str, '$.intersectionKey'), 'ITEM:[[:space:]]*([^,]+)', 1, 1, NULL, 1 ) AS item, json_str FROM audit_data;
说明
JSON_VALUE(json_str, '$.intersectionKey'):直接从JSON字符串中提取intersectionKey的内容,得到类似LOC: FR01, ITEM: 16651903的字符串- 再用正则从该字符串中提取ITEM编码,逻辑更聚焦,出错概率更低
内容的提问来源于stack exchange,提问作者khris jones
相关产品推荐
相关产品推荐

