0

I have an emp table, i.e.

insert into emp(id,name,salary) values (1,'name1',1000);
insert into emp(id,name,salary) values (2,'name2',2000);
insert into emp(id,name,salary) values (3,'name3',3000);
insert into emp(id,name,salary) values (4,'name4',4000);
insert into emp(id,name,salary) values (5,'name5',5000);

And I would like to have a query to output as an array of json object with additional language field.

After many retries, the closest I can get is with below:

declare 
    type v_lang_type is table of varchar2(20); 
    v_langs v_lang_type; 
    result clob; 
begin 
  v_langs := v_lang_type('EN','DE','SG','ES');   
FOR I IN v_langs.first .. v_langs.LAST 
  LOOP 
select json_arrayagg( 
    json_object( 
    'id' is id, 
    'name' is name, 
    'salary' is salary, 
    'lang' value v_langs(I) 
) format json returning clob) into result from emp; 
 dbms_output.put_line( result );
END LOOP; 
 
end;

Below is the result so far.

[{"id":1,"name":"name1","salary":1000,"lang":"EN"},{"id":2,"name":"name2","salary":2000,"lang":"EN"},{"id":3,"name":"name3","salary":3000,"lang":"EN"},{"id":4,"name":"name4","salary":4000,"lang":"EN"},{"id":5,"name":"name5","salary":5000,"lang":"EN"}]
[{"id":1,"name":"name1","salary":1000,"lang":"DE"},{"id":2,"name":"name2","salary":2000,"lang":"DE"},{"id":3,"name":"name3","salary":3000,"lang":"DE"},{"id":4,"name":"name4","salary":4000,"lang":"DE"},{"id":5,"name":"name5","salary":5000,"lang":"DE"}]
[{"id":1,"name":"name1","salary":1000,"lang":"SG"},{"id":2,"name":"name2","salary":2000,"lang":"SG"},{"id":3,"name":"name3","salary":3000,"lang":"SG"},{"id":4,"name":"name4","salary":4000,"lang":"SG"},{"id":5,"name":"name5","salary":5000,"lang":"SG"}]
[{"id":1,"name":"name1","salary":1000,"lang":"ES"},{"id":2,"name":"name2","salary":2000,"lang":"ES"},{"id":3,"name":"name3","salary":3000,"lang":"ES"},{"id":4,"name":"name4","salary":4000,"lang":"ES"},{"id":5,"name":"name5","salary":5000,"lang":"ES"}]

While the target I would like to achieve is this:

[
    {
        "id": 1,
        "language": "EN",
        "name": "name1",
        "salary": 1000
    },
    {
        "id": 2,
        "language": "EN",
        "name": "name2",
        "salary": 2000
    },
    {
        "id": 3,
        "language": "EN",
        "name": "name3",
        "salary": 3000
    },
    {
        "id": 1,
        "language": "DE",
        "name": "name1",
        "salary": 1000
    },
    {
        "id": 2,
        "language": "DE",
        "name": "name2",
        "salary": 2000
    },
    {
        "id": 3,
        "language": "DE",
        "name": "name3",
        "salary": 3000
    },
    {
        "id": 1,
        "language": "SG",
        "name": "name1",
        "salary": 1000
    },
    {
        "id": 2,
        "language": "SG",
        "name": "name2",
        "salary": 2000
    },
    {
        "id": 3,
        "language": "SG",
        "name": "name3",
        "salary": 3000
    },
    {
        "id": 1,
        "language": "ES",
        "name": "name1",
        "salary": 1000
    },
    {
        "id": 2,
        "language": "ES",
        "name": "name2",
        "salary": 2000
    },
    {
        "id": 3,
        "language": "ES",
        "name": "name3",
        "salary": 3000
    }
]

Any idea or pointer on how to achieve that?

1 Answer 1

0

Does it need to be pl/sql ? In sql this is possible. JSON_ARRAYAGG generates a single array. By using CROSS JOIN and representing the language value as a table it's possible to generate the complete json object in a single select

create table emp2 (id,name,salary) AS
(
select 1, 'name1', 1000 from dual union all
select 2, 'name2', 2000 from dual union all
select 3, 'name3', 3000 from dual 
);

Table EMP2 created.

Elapsed: 00:00:00.300

SELECT JSON_ARRAYAGG (
        JSON_OBJECT(
        KEY 'id' VALUE e.id,
        KEY 'name' VALUE e.name,
        KEY 'salary' VALUE e.salary,
        KEY 'lang' VALUE l.lang
        )
    )
FROM   emp2 e CROSS JOIN 
(SELECT 'EN' AS lang from dual union all
SELECT 'DE' AS lang from dual union all
SELECT 'SG' AS lang from dual
) l;

[
  {
    "id": 1,
    "name": "name1",
    "salary": 1000,
    "lang": "EN"
  },
  {
    "id": 2,
    "name": "name2",
    "salary": 2000,
    "lang": "EN"
  },
  {
    "id": 3,
    "name": "name3",
    "salary": 3000,
    "lang": "EN"
  },
  {
    "id": 1,
    "name": "name1",
    "salary": 1000,
    "lang": "DE"
  },
  {
    "id": 2,
    "name": "name2",
    "salary": 2000,
    "lang": "DE"
  },
  {
    "id": 3,
    "name": "name3",
    "salary": 3000,
    "lang": "DE"
  },
  {
    "id": 1,
    "name": "name1",
    "salary": 1000,
    "lang": "SG"
  },
  {
    "id": 2,
    "name": "name2",
    "salary": 2000,
    "lang": "SG"
  },
  {
    "id": 3,
    "name": "name3",
    "salary": 3000,
    "lang": "SG"
  }
]

for pl/sql, well just use that same query.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.