work with json in oracle

后端 未结 6 653
梦谈多话
梦谈多话 2020-12-02 15:06

Is there an easy way to work with JSON within oracle? I have a standard procedure that I use to call web services quite often, JSON is a format that I am familiar with in w

相关标签:
6条回答
  • 2020-12-02 15:16

    Oracle APEX 5.0 has support for JSON using APEX_JSON package. I haven't used it but it looks interesting and I have asked my team to explore it. Our use case is to be able to pass JSON data as input parameter to stored procedure from nodejs application.

    0 讨论(0)
  • 2020-12-02 15:17

    I wrote this library : http://reseau.erasme.org/pl-sql-library-for-JSON?lang=en, and this works great to get some json response into a plsql table.

    If you only want to extract Oracle data and transform it in Json, this library is a bit "Heavy to use"... I can propose you another code doing it better and faster :

    create or replace package jsonfly as
    
    procedure open_object(k varchar2 default null);
    procedure close_object;
    procedure open_array (k varchar2 default null);
    procedure close_array;
    procedure separation;
    procedure member(k varchar2, v varchar2);
    procedure member(k varchar2, n number);
    procedure send;
    end;
    /
    
    create or replace package body jsonfly as
    --------------------------------------------------------------------------------
    -- package pour générer du JSON, envoyé à la volé
    --------------------------------------------------------------------------------
    type tCache is table of varchar2(2000) index by binary_integer;
    
    g_openBrace         constant varchar2(2) := '{ ';
    g_closeBrace        constant varchar2(2) := ' }';
    g_openBracket       constant varchar2(2) := '[ ';
    g_closeBracket      constant varchar2(2) := ' ]';
    g_stringDelimiter   constant varchar2(1) := '"';
    g_Affectation       constant varchar2(3) := ' : ';
    g_separation        constant varchar2(3) := ', ';
    g_CR                constant varchar2(1) := Chr(10); -- used to indent the JSON object correctly
    g_spc               constant varchar2(2) := '  ';     -- used to indent the JSON object correctly
    g_js_comment_open   constant varchar2(20) := '/*-secure-\n'; -- used to prevent from javascript hijacking
    g_js_comment_close  constant varchar2(20) := '\n*/';          -- used to prevent from javascript hijacking
    
    --isObjectOpened  boolean := false;
    --isArrayOpened   boolean := false;
    t tCache;
    i number := 1;
    
    --------------------------------------------------------------------------------
    -- 
    --------------------------------------------------------------------------------
    procedure p(s  varchar2) is
    begin
        t(i) := s;
        i := i + 1;
    end;
    --------------------------------------------------------------------------------
    -- 
    --------------------------------------------------------------------------------
    function encap (s varchar2) return varchar2 is
    begin
        return g_stringdelimiter || s || g_stringdelimiter;
    end;
    
    --------------------------------------------------------------------------------
    -- 
    --------------------------------------------------------------------------------
    function encode_string(p_string varchar2) return varchar2 is
    begin
        return replace(replace(replace(replace(replace(replace(replace(replace(p_string, 
            '\', '\\'), 
            '"', '\"'), 
            '/', '\/'), 
            chr(8), '\b'), 
            chr(9), '\t'), 
            chr(10), '\n'), 
            chr(12), '\f'), 
            chr(13), '\r');
    end;
    
    --------------------------------------------------------------------------------
    -- 
    --------------------------------------------------------------------------------
    procedure open_object(k varchar2 default null) is
    begin    
        if ( k is null ) then 
            p(g_openbrace);
        else 
            p( encap(k) || g_affectation || g_openbrace);
        end if; 
    end;
    
    --------------------------------------------------------------------------------
    -- 
    --------------------------------------------------------------------------------
    procedure close_object is
    begin
        if (t(i-1) = g_separation) then
            i := i - 1;
        end if; 
        p(g_closebrace);
        separation();
    end;
    
    --------------------------------------------------------------------------------
    -- 
    --------------------------------------------------------------------------------
    procedure open_array (k varchar2 default null) is
    begin    
        if ( k is null ) then 
        p(g_openbracket);
        else 
            p( encap(k) || g_affectation || g_openbracket);
        end if; 
    end;
    
    --------------------------------------------------------------------------------
    -- 
    --------------------------------------------------------------------------------
    procedure close_array is
    begin
        if (t(i-1) = g_separation) then
            i := i - 1;
        end if; 
        p(g_closebracket);
        separation();
    end;
    
    --------------------------------------------------------------------------------
    -- 
    --------------------------------------------------------------------------------
    procedure separation is
    begin
        p(g_separation);
    end;
    
    --------------------------------------------------------------------------------
    -- 
    --------------------------------------------------------------------------------
    procedure key(k varchar2) is
    begin
       p( encap(k) || g_affectation);
    end;
    
    --------------------------------------------------------------------------------
    -- 
    --------------------------------------------------------------------------------
    procedure value(v varchar2) is
    begin
       p(v);
    end;
    
    --------------------------------------------------------------------------------
    -- 
    --------------------------------------------------------------------------------
    procedure member(k varchar2, v varchar2) is
    begin
        p( encap(k) || g_affectation || encap(encode_string(v)));
        p(g_separation);
    end;
    
    --------------------------------------------------------------------------------
    -- 
    --------------------------------------------------------------------------------
    procedure member(k varchar2, n number) is
    begin
        p( encap(k) || g_affectation || n );
        p(g_separation);
    end;
    
    --------------------------------------------------------------------------------
    -- 
    --------------------------------------------------------------------------------
    procedure send is
    begin
        if (t(i-1) = g_separation) then
            t.delete(i-1);
        end if; 
    
        i := t.first;
        while (i is not null) loop
            htp.p(t(i));
            i := t.next(i);
        end loop;
    end;
    
    
    end jsonfly;
    /
    
    0 讨论(0)
  • 2020-12-02 15:17

    Oracle 12c now have native JSON support:

    Oracle Database supports JavaScript Object Notation (JSON) data natively with relational database features, including transactions, indexing, declarative querying, and views

    JSON data and XML data can be used in Oracle Database in similar ways. Unlike relational data, both can be stored, indexed, and queried without any need for a schema that defines the data. Oracle Database supports JSON natively with relational database features, including transactions, indexing, declarative querying, and views.

    JSON data has often been stored in NoSQL databases such as Oracle NoSQL Database and Oracle Berkeley DB. These allow for storage and retrieval of data that is not based on any schema, but they do not offer the rigorous consistency models of relational databases.

    To compensate for this shortcoming, a relational database is sometimes used in parallel with a NoSQL database. Applications using JSON data stored in the NoSQL database must then ensure data integrity themselves.

    Native support for JSON by Oracle Database obviates such workarounds. It provides all of the benefits of relational database features for use with JSON, including transactions, indexing, declarative querying, and views.

    Oracle Database queries are declarative. You can join JSON data with relational data. And you can project JSON data relationally, making it available for relational processes and tools. You can also query, from within the database, JSON data that is stored outside the database in an external table.

    You can access JSON data stored in the database the same way you access other database data, including using OCI, .NET, and JDBC.

    Unlike XML data, which is stored using SQL data type XMLType, JSON data is stored in Oracle Database using SQL data types VARCHAR2, CLOB, and BLOB. Oracle recommends that you always use an is_json check constraint to ensure that column values are valid JSON instances

    0 讨论(0)
  • 2020-12-02 15:17

    Life is happy try this:

    CLOB or 20000000 characters JSON

    with data as
      ( select 
        xmlelement(e,regexp_replace('{"name":"'||colname||'"}', '[[:cntrl:]]', ''),',') col1
        from tblname
      )
      select
            rtrim(replace(replace(replace(xmlagg(col1).getclobval(),'&'||'quot;','"'),'<E>',''),'</E>',''),',')
            as very_long_json
      from data;
    
    0 讨论(0)
  • 2020-12-02 15:23

    I have started using this library, and it seems promising: https://github.com/pljson/pljson

    Easy to install, and the examples are good.

    To use the library in your example, add these variables to your procedure..

    mapData     json;
    results     json_list;
    status      json_value;
    firstResult json;
    geometry    json;
    

    ....

    Then you can manipulate the response as a json object.

    -- convert the result from the get to a json object, and show some results.
    mapData := json(v_ans);
    
    -- Show the status of the request
    status := mapData.get('status');
    dbms_output.put_line('Status = ' || status.get_string());
    
    IF (status.get_string() = 'OK') THEN
      results := json_list(mapData.get('results'));
      -- Grab the first item in the list
      resultObject := json(results.head);
    
      -- Show the human readable address 
      dbms_output.put_line('Address = ' || resultObject.get('formatted_address').to_char() );
      -- Show the json location data 
      dbms_output.put_line('Location = ' || resultObject.get('geometry').to_char() );
    END IF;
    

    Running this code will output this to the dbms output:

    Status = OK
    Address = "St Paul, MN 55105, USA"
    Location = {
      "bounds" : {
        "northeast" : {
          "lat" : 44.9483849,
          "lng" : -93.1261959
        },
        "southwest" : {
          "lat" : 44.9223829,
          "lng" : -93.200307
        }
      },
      "location" : {
        "lat" : 44.9330076,
        "lng" : -93.16290629999999
      },
      "location_type" : "APPROXIMATE",
      "viewport" : {
        "northeast" : {
          "lat" : 44.9483849,
          "lng" : -93.1261959
        },
        "southwest" : {
          "lat" : 44.9223829,
          "lng" : -93.200307
        }
      }
    }
    
    0 讨论(0)
  • 2020-12-02 15:33

    It should be noted that as of Oracle 12c there is some native support of JSON. However i don't think in the current form it's as useful as the like of PLJSON included in another answer.

    To use the feature you create a table with a BLOB, CLOB or Varchar2 field and add a constraint against it "column IS JSON". This enforces JSON syntax checking on that column.

    As long as the "IS JSON" constraint is in place you can access the JSON values within using dot notation from SQL. To me, it doesn't seem to provide as powerful manipulation as PLJSON. You can also create an XMLType and then convert to JSON.

    Useful links:
    Oracle docs
    Good tutorial and examples
    Tutorial including XML to JSON

    0 讨论(0)
提交回复
热议问题