将字符串转换为内存表形式的SQL语句

本文介绍了一个Oracle函数f_str2tab,该函数将输入的逗号分隔字符串转换为内存表形式,并提供了使用示例。

 create or replace type type_varc is table of varchar2(1000);

 

CREATE OR REPLACE FUNCTION f_str2tab(p_str IN VARCHAR2 --传入的字符串,格式为1,2,3,4,5
) RETURN type_varc IS
/******************************************************************
Ver1.0 Created by xsb on 2008-04-14
把字符串(1,2,3,4,5)转换为内存表形式
create or replace type type_varc is table of varchar2(1000);
测试用例:SELECT * FROM TABLE(f_str2tab('a,s,d,12,3,4,5'));
******************************************************************/
v_str VARCHAR2(4000) := p_str || ',';
v_cnt NUMBER := length(v_str) - length(REPLACE(v_str, ','));
v_numtab type_varc := type_varc(); --返回内存表

BEGIN
FOR i IN 1 .. v_cnt LOOP
v_numtab.EXTEND;
v_numtab(i) := substr(v_str, 1, instr(v_str, ',') - 1);
dbms_output.put_line('v_str:'||v_str);
dbms_output.put_line('v_numtab(i):'||v_numtab(i));
v_str := substr(v_str, instr(v_str, ',') + 1);
dbms_output.put_line('v_str:'||v_str);
END LOOP;
RETURN v_numtab;

EXCEPTION
WHEN OTHERS THEN
v_numtab.DELETE;

END;

--上面的可能会有重复的元素出现
select distinct * from  TABLE(f_str2tab('a,s,d,12,12,3,4,5'))


使用此内存表关联时,需要加hint,如:
select /*+ ordered use_nl(a,b)*/ b.*
from TABLE(f_str2tab('a,s,d,12,3,4,5')) a,t1 b
where a.column_value=b.id1;

 

<think> 嗯,用户这次的问题非常具体,是关于在Oracle中准确读取JSON字符串SQL方法。从用户引用的资料来看,ta显然已经查阅过Oracle文档和相关技术文章,但可能被零散的信息困扰。用户特别强调"准确"二字,说明ta需要的是经过验证的可靠方案。 用户引用[2]提到项目里遇到JSON列检索效率低的问题,看来ta正面临实际的生产难题。那种全扫描再逐行解析JSON的做法确实可怕,难怪用户着急。引用[3]和[4]则明ta已经尝试过基础方案但可能遇到语法细节问题。 注意到用户是开发者身份,且对MongoDB有了解,可以推测ta期待的是接近NoSQL的查询体验。不过Oracle 12c+的JSON功能其实相当完善,关键在于正确使用SQL/JSON语法。用户引用[1]里Oracle官方强调的兼容性和性能优势,正好是可以说服ta继续采用Oracle方案的切入点。 需要重点解决三个层次的需求:基础路径查询、带条件过滤、处理复杂结构。用户引用[4]的Java对象映射需求也值得关注,虽然ta这次没直接问,但后续很可能会遇到。考虑到用户项目的紧迫性,示例要给出可直接运行的SQL片段。 特别要注意语法细节:Oracle 12.1和12.2的JSON语法有差异,18c的JSON_QUERY行为变化等。用户引用[3]里那个凌乱的转义符示例,恰恰说明网上存在大量错误示范,必须明确标注版本差异。 </think> 在 Oracle 中准确读取 JSON 字符串SQL 语句主要使用内置的 **SQL/JSON 函数**(自 Oracle Database 12c Release 1 引入并持续增强)。以下是关键方法和示例: --- ### **核心函数与方法** 1. **`JSON_VALUE`** *提取标量值(字符串、数字、布尔值)* 语法: ```sql JSON_VALUE(json_column, '$.path.to.key' [RETURNING datatype] [ERROR | NULL ON ERROR]) ``` 示例(提取名为 "name" 的字段): ```sql SELECT JSON_VALUE(json_data, '$.name') AS employee_name FROM your_table WHERE id = 1; ``` 2. **`JSON_QUERY`** *提取 JSON 对象或数组(返回字符串形式)* 语法: ```sql JSON_QUERY(json_column, '$.path.to.object' [RETURNING CLOB] [WITH WRAPPER | WITHOUT WRAPPER]) ``` 示例(提取整个 "address" 对象): ```sql SELECT JSON_QUERY(json_data, '$.address') AS full_address FROM your_table; ``` 3. **`JSON_TABLE`** *将 JSON 数组或对象转换为关系格式(支持多值提取和条件过滤)* 语法: ```sql SELECT jt.* FROM your_table t, JSON_TABLE( t.json_column, '$' COLUMNS ( employee_name VARCHAR2(50) PATH '$.name', salary NUMBER PATH '$.salary', department VARCHAR2(20) PATH '$.dept' ) ) jt WHERE t.id = 100; ``` --- ### **实际应用场景示例** #### 场景 1:提取嵌套值 + 条件过滤 ```sql -- 查找薪资大于 5000 的员工的姓名和部门 SELECT JSON_VALUE(json_data, '$.name') AS name, JSON_VALUE(json_data, '$.dept') AS department FROM employees WHERE CAST(JSON_VALUE(json_data, '$.salary' RETURNING NUMBER) > 5000; ``` #### 场景 2:解析 JSON 数组(使用 `JSON_TABLE`) ```sql -- 解析存储考试规则的 JSON 数组 [^4] SELECT exam.exam_name, rule.type, rule.num, rule.score FROM exams e, JSON_TABLE( e.random_rule, '$[*]' COLUMNS ( type VARCHAR2(20) PATH '$.type', num NUMBER PATH '$.num', score NUMBER PATH '$.score' ) ) rule; ``` #### 场景 3:处理复杂路径(带转义) ```sql -- 提取含特殊字符的键值(如 "employee.name") SELECT JSON_VALUE(json_data, '$."employee.name"') AS emp_name FROM config_table; ``` --- ### **注意事项** 1. **数据类型转换** 使用 `RETURNING` 子句显式指定类型(如 `RETURNING NUMBER`),避免隐式转换错误。 2. **路径达式语法** - 点号 `.` 访问嵌套键:`$.user.address.city` - 方括号访问数组:`$.items[0].id` - 双引号包裹含空格/特殊字符的键:`$."first name"` 3. **空值/错误处理** 添加 `NULL ON ERROR` 避免无效路径导致查询中断: ```sql JSON_VALUE(json_data, '$.invalid_path' NULL ON ERROR) AS safe_value ``` 4. **性能优化** - **创建 JSON 搜索索引**(12.2+)加速过滤: ```sql CREATE SEARCH INDEX json_idx ON your_table (json_column) FOR JSON; ``` - 优先在 `WHERE` 子句中使用 `JSON_VALUE` 而非内存过滤 [^1]。 --- ### **版本兼容性** | 版本 | 支持功能 | |---------------|-----------------------------| | **Oracle 12.1** | `JSON_VALUE`, `JSON_QUERY` | | **Oracle 12.2** | `JSON_TABLE`, JSON 搜索索引 | | **Oracle 21c** | JSON 数据类型(`JSON`)、JSON 模式验证 | ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值