Skip to main content

JSON and PL/SQL 12.2: Get values from JSON documents with API


With the release of Oracle Database 12c,  Oracle SQL entered the Age of JSON. You can use SQL to join JSON data with relational data. You can extract content from within the JSON document, and make it available for relational processes and tools. You can even query, right from within the database, JSON data that is stored outside Oracle Database in an external table. Check out my post on JSON resources for more guidance on all of the above.

And that was all possible in 12.1. In Oracle Database 12c Release 2, we added several pre-defined PL/SQL object types to perform fine-grained programmatic construction and manipulation of in-memory JSON data. I'll publish occasional posts on what you can do with these types. Here's the first one, showing you how to get the value for a specific key in a JSON document.

Suppose I've created and populated my species table as follows:

CREATE TABLE json_species
(
   id     NUMBER NOT NULL PRIMARY KEY,
   info   CLOB CONSTRAINT is_json CHECK (info IS JSON ) )
/

BEGIN
   INSERT INTO json_species
        VALUES (1, '{"name":"Spider"}');

   INSERT INTO json_species
        VALUES (2, '{"name":"Elephant", "trunk_length":"10"}');

   INSERT INTO json_species
        VALUES (3, '{"name":"Shark", "fin_count":"4"}');

   COMMIT;
END;
/

If I want to see the values for names in the JSON documents in this table, I can use SQL:

SELECT sp.info.name
  FROM json_species sp


And if this is all you need, there's no reason to bring in the PL/SQL types. If, however, you need to get values in order to perform additional processing on them and perhaps even change the values, the PL/SQL API comes in handy.

So here's how I can get those same values (and display them) in PL/SQL:

DECLARE
   CURSOR species_cur
   IS
      SELECT id, sp.info
        FROM json_species sp
       ORDER BY id;

   l_species   json_object_t;
   l_name      json_element_t;
BEGIN
   FOR rec IN species_cur
   LOOP
      l_species := json_object_t (rec.info);
      l_name := l_species.get ('name');
      DBMS_OUTPUT.put_line (l_name.to_string);
   END LOOP;
END;
/

An explanation of this code:
  • Declare an instance of the JSON_OBJECT_T type.
  • Declare an instance of the JSON_ELEMENT_T type.
  • For every row in the table, get the JSON document (info column) - which, remember is a CLOB, not a JSON document.
  • Create a JSON document from that CLOB by calling the JSON_OBJECT_T constructor function.
  • Call the GET member function of the JSON_OBJECT_T type on the l_species object to get the element for "name". 
  • Call the TO_STRING member function of the JSON_ELEMENT_T type to convert the JSON element into a string.
  • Display that string.
And I see this output:

"Spider"
"Elephant"
"Shark"

[well, I will see all that text, maybe not in that exact order, since I didn't specify an ORDER BY clause in my SELECT. Always good to remember that!]

That was the step-by-step approach, which you will want to use when you are just getting started with these types. If, however, all I wanted to do in PL/SQL was display the value (which I could, remember, do with "pure"  SQL), I could write and execute nothing more than this:

BEGIN
   FOR rec IN (SELECT sp.info FROM json_species sp)
   LOOP
      dbms_output.put_line (
         json_object_t (rec.info).get ('name').to_string);
   END LOOP;
END;
/

Sure, nothing fancy there. And there's lots more to explore. So:

1. If you reading this post before February 8, 2018, be sure to sign up for a CodeTalk session on JSON and PL/SQL I am doing with Darryl Hurley of Implestrat. He knows a lot more about this stuff than me! (for now, anyway :-) )

2. Check out my LiveSQL script with the above code and more.

3. I will be publishing more on this in the weeks to come.

Comments

  1. The link " CodeTalk session on JSON and PL/SQL" is wrong, it has a dot at the end.

    ReplyDelete
  2. Nice article and want to suggest a tool which is developed by me. https://jsonformatter.org for JSON lovers.

    ReplyDelete
  3. Where did Ostrich come from? You only inserted Spider, Elephant and Shark,

    ReplyDelete
    Replies
    1. Excellent question. :-) Ostrich made an appearance in the LiveSQL script but does not belong here. I will remove it. Thanks for the close reading!

      Delete

Post a Comment

Popular posts from this blog

Why DBMS_OUTPUT.PUT_LINE should not be in your application code

A database developer recently came across my  Bulletproof PL/SQL  presentation, which includes this slide. That first item in the list caught his attention: Never put calls to DBMS_OUTPUT.PUT_LINE in your application code. So he sent me an email asking why I would say that. Well, I suppose that is the problem with publishing slide decks. All the explanatory verbiage is missing. I suppose maybe I should do a video. :-) But in the meantime, allow me to explain. First, what does DBMS_OUTPUT.PUT_LINE do? It writes text out to a buffer, and when your current PL/SQL block terminates, the buffer is displayed on your screen. [Note: there can be more to it than that. For example, you could in your own code call DBMS_OUTPUT.GET_LINE(S) to get the contents of the buffer and do something with it, but I will keep things simple right now.] Second, if I am telling you not to use this built-in, how could text from your program be displayed on your screen? Not without a lot o...

The future of Oracle PL/SQL: some thoughts on Sten Vesterli's thoughts

Sten Vesterli published a very thought-provoking post on his blog: Please stop reading this post, and read that one. When you are done, come on back here for my thoughts on Sten's thoughts. OK. You read it. Here we go. First, thanks, Sten, for being such an interesting, wise, sometimes provocative voice in our community. Next, Sten writes: Now, on the one hand, I certainly agree that the vast majority of young developers are currently caught up in the modern version of a Gold Rush, which is: "Build an app using JavaScript, pay no attention to that database behind the curtain." But I can assure you that I still do meet young PL/SQL programmers, regularly, when I am at conferences and doing onsite presentations at companies. So, young person who writes PL/SQL: do not be afraid! You are not alone! And you are super-smart to have made the choice you did. :-) Next, Sten offers this advice to managers: I agree that PL/SQL is a "spec...

Table Functions, Part 1: Introduction and Exploration

Please do feel encouraged to read this and my other posts on table functions, but you will learn much more about table functions by taking my Get Started with PL/SQL Table Functions class at the Oracle Dev Gym. Videos, tutorials and quizzes - then print a certificate when you are done! Table functions - functions that can be called in the FROM clause of a query from inside the TABLE operator - are fascinating and incredibly helpful constructs. So I've decided to write a series of blog posts on them: how to build them, how to use them, issues you might run into. Of course, I am not the first to do so. I encourage to check out the  documentation , as well as excellent posts from Adrian Billington (search for "table functions") and Tim Hall . Adrian and Tim mostly focus on pipelined table functions, a specialized variant of table functions designed to improve performance and reduce PGA consumption. I will take a look at pipelined table functions in the latter part...