【问题标题】:Parse JSON into Oracle table using PL/SQL使用 PL/SQL 将 JSON 解析为 Oracle 表
【发布时间】:2015-01-23 05:08:49
【问题描述】:

我创建了以下脚本,以便从 Oracle SQL Developer 的 Mobile App DB(基于 MongoDB)中读取数据:

宣布 l_param_list VARCHAR2(512); l_http_request UTL_HTTP.req; l_http_response UTL_HTTP.resp; l_response_text VARCHAR2(32767); 开始 -- 服务的输入参数 -- 准备请求... l_http_request := UTL_HTTP.begin_request ('https://api.appery.io/rest/1/db/collections/Photos?where=%7B%22Oracle_Flag%22%3A%22Y%22%7D' , '得到' , 'HTTP/1.1'); -- ...设置标题的属性 UTL_HTTP.set_header(l_http_request, 'X-Appery-Database-Id', '53f2dac5e4b02cca64021dbe'); --UTL_HTTP.set_header(l_http_request, '内容长度', LENGTH(l_param_list)); -- ...设置输入参数 -- UTL_HTTP.write_text(l_http_request, l_param_list); -- 获取响应并获取接收值 l_http_response := UTL_HTTP.get_response(l_http_request); UTL_HTTP.read_text(l_http_response, l_response_text); DBMS_OUTPUT.put_line(l_response_text); 插入appery值(l_response_text); -- 最终确定 UTL_HTTP.end_response(l_http_response); 例外 WHEN UTL_HTTP.end_of_body 然后 UTL_HTTP.end_response(l_http_response); 结尾; /

响应 (l_response_text) 是一个类似 JSON 的字符串。例如:

[{"Postcode":"47100","OutletCode":"128039251","MobileNumber":"0123071303","_createdAt":"2014-11-10 06:12:49.837","_updatedAt": "2014-11-10 06:12:49.837"}, {"邮编":"32100","OutletCode":"118034251", .....]

代码运行良好,并将响应插入到一个名为 appery 的列表中。但是,我需要解析这个响应,以便每个数组进入一个名为 appery_test 的表中的特定列。 appery_test 表的列数与 JSON 对数相同,顺序相同。

我搜索了大部分关于将 Oracle 表解析为 JSON 的结果,而不是相反。不过,我发现this 链接与我的问题有些相似。但是,答案中建议的库没有任何示例说明如何使用它将 JSON 插入使用 PL/SQL 的常规表中。

注意:我使用的是 11g 而不是 12c。所以built in 函数对我不可用。

【问题讨论】:

    标签: sql json plsql oracle11g


    【解决方案1】:

    由于这个问题的结果得分很高,我想发布这个首选的替代方案:

    Oracle 已发布APEX 5.0(2015 年 4 月 15 日)。有了它,您可以访问一个很棒的 AP​​I 来处理 JSON

    我在 11.2 上使用它,并且能够处理每个 json,从简单到非常复杂的具有多个数组和 4/5 级别的对象。 APEX_JSON

    如果您不想使用 APEX。只需安装运行时环境即可访问 API。

    使用示例,来自json.org's example 的数据:

    declare
        sample_json   varchar2 (32767)
            := '{
        "glossary": {
            "title": "example glossary",
            "GlossDiv": {
                "title": "S",
                "GlossList": {
                    "GlossEntry": {
                        "ID": "SGML",
                        "SortAs": "SGML",
                        "GlossTerm": "Standard Generalized Markup Language",
                        "Acronym": "SGML",
                        "Abbrev": "ISO 8879:1986",
                        "GlossDef": {
                            "para": "A meta-markup language, used to create markup languages such as DocBook.",
                            "GlossSeeAlso": ["GML", "XML"]
                        },
                        "GlossSee": "markup"
                    }
                }
            }
        }
    }';
    begin
        apex_json.parse (sample_json);
        dbms_output.put_line (apex_json.get_varchar2 ('glossary.GlossDiv.title'));
        dbms_output.put_line (apex_json.get_varchar2 ('glossary.GlossDiv.GlossList.GlossEntry.GlossTerm'));
        dbms_output.put_line (apex_json.get_varchar2 ('glossary.GlossDiv.GlossList.GlossEntry.GlossDef.GlossSeeAlso[%d]', 2));
    end;
    

    结果: 执行的 PL/SQL 块

    S
    Standard Generalized Markup Language
    XML
    

    【讨论】:

      【解决方案2】:

      我使用了PL/JSON library。具体来说,JSON_EXT 封装函数以便对其进行解析。

      以下受 Oracle 社区答案启发的脚本对我有用

      宣布 l_param_list VARCHAR2(512); l_http_request UTL_HTTP.req; l_http_response UTL_HTTP.resp; l_response_text VARCHAR2(32767); l_list json_list; A_id VARCHAR2(200); 用户 ID VARCHAR2(100); 用户名 VARCHAR2(100); 出口代码 VARCHAR2(100); 出口名称 VARCHAR2(100); 手机号码 VARCHAR2(100); 电话号码 VARCHAR2(100); 地址 VARCHAR2(100); 城市 VARCHAR2(100); 状态 VARCHAR2(100); 邮政编码 VARCHAR2(100); 电子邮件 VARCHAR2(100); 更新计数 VARCHAR2(100); loginCount VARCHAR2(100); 参考照片 VARCHAR2(100); 更新 VARCHAR2(100); AccountLocked VARCHAR2(100); Oracle_Flag VARCHAR2(100); acl VARCHAR2(100); 开始 -- 服务的输入参数 -- 准备请求... l_http_request := UTL_HTTP.begin_request('https://api.appery.io/rest/1/db/collections/Outlet_Details?where=%7B%22Oracle_Flag%22%3A%22Y%22%7D' , '得到' , 'HTTP/1.1'); -- ...设置标题的属性 UTL_HTTP.set_header(l_http_request, 'X-Appery-Database-Id', '53f2dac5e4b02cca64021dbe'); --UTL_HTTP.set_header(l_http_request, '内容长度', LENGTH(l_param_list)); -- ...设置输入参数 -- UTL_HTTP.write_text(l_http_request, l_param_list); -- 获取响应并获取接收值 l_http_response := UTL_HTTP.get_response(l_http_request); UTL_HTTP.read_text(l_http_response, l_response_text); DBMS_OUTPUT.put_line(l_response_text); l_list := json_list(l_response_text); FOR i IN 1..l_list.count 环形 A_id := json_ext.get_string(json(l_list.get(i)),'_id'); UserId := json_ext.get_string(json(l_list.get(i)),'UserId'); 用户名 := json_ext.get_string(json(l_list.get(i)),'UserName'); OutletCode := json_ext.get_string(json(l_list.get(i)),'OutletCode'); OutletName := json_ext.get_string(json(l_list.get(i)),'OutletName'); MobileNumber := json_ext.get_string(json(l_list.get(i)),'MobileNumber'); PhoneNumber := json_ext.get_string(json(l_list.get(i)),'PhoneNumber'); 地址 := json_ext.get_string(json(l_list.get(i)),'地址'); 城市 := json_ext.get_string(json(l_list.get(i)),'City'); 状态:= json_ext.get_string(json(l_list.get(i)),'State'); 邮政编码:= json_ext.get_string(json(l_list.get(i)),'邮政编码'); 电子邮件 := json_ext.get_string(json(l_list.get(i)),'Email'); UpdateCount := json_ext.get_string(json(l_list.get(i)),'UpdateCount'); loginCount := json_ext.get_string(json(l_list.get(i)),'loginCount'); ReferencePhoto := json_ext.get_string(json(l_list.get(i)),'ReferencePhoto'); 更新:= json_ext.get_string(json(l_list.get(i)),'Updates'); AccountLocked := json_ext.get_string(json(l_list.get(i)),'AccountLocked'); Oracle_Flag := json_ext.get_string(json(l_list.get(i)),'Oracle_Flag'); acl := json_ext.get_string(json(l_list.get(i)),'acl'); 插入 .....

      请注意,json_ext.get_string 仅返回 VARCHAR2,最大限制为 32767。为了使用具有更大 json_list 和 json_values (>32KB) 的相同包,请检查 here

      如果您拥有 APEX 5.0 及更高版本,则可以通过 APEX_JSON 包获得更好的选择和更好的性能。详情见@Olafur Tryggvason的回答

      【讨论】:

        【解决方案3】:

        Orace 为 JSON 处理提供 PL/SQL DOM API。强烈推荐使用它,因为它提供了大量有用的 API。

        https://docs.oracle.com/database/122/ADJSN/using-PLSQL-object-types-for-JSON.htm#GUID-F0561593-D0B9-44EA-9C8C-ACB6AA9474EE

        【讨论】:

        【解决方案4】:

        在甲骨文 12 中: https://docs.oracle.com/database/121/SQLRF/functions092.htm#SQLRF56973

        SELECT jt.*
        FROM j_purchaseorder,
        JSON_TABLE(po_document, '$.ShippingInstructions.Phone[*]'
        COLUMNS (row_number FOR ORDINALITY,
                 phone_type VARCHAR2(10) PATH '$.type',
                 phone_num VARCHAR2(20) PATH '$.number'))
        AS jt;
        
        ROW_NUMBER PHONE_TYPE PHONE_NUM
        ---------- ---------- --------------------
                 1 Office     909-555-7307
                 2 Mobile     415-555-1234
        

        【讨论】:

          猜你喜欢
          • 2021-12-28
          • 1970-01-01
          • 1970-01-01
          • 2012-08-15
          • 2015-11-03
          • 1970-01-01
          • 2014-10-23
          • 2022-06-14
          • 1970-01-01
          相关资源
          最近更新 更多