Jorge J. Espada
Jorge J. Espada

Reputation: 31

Generate JSON from stored function/procedure that returns the result of an SQL?

I am testing PLJSON on Oracle 12.1, with the intention of generating JSON from a table. I have implemented a package that encapsulates queries to that table. I have also verified that, using pljson_dyn, I can generate JSON correctly from an SQL query to the table. However, if I replace the query with a call to the function that returns the data in the table, it fails. Is there any possibility of making this option?

Code returning ok from a select:

set serveroutput on;
declare 
  ret json_list;
begin
  ret := json_dyn.executeList('select id, denounidad from tgeounipoblacionales where tgeomunicipio_id = 6015');  
  ret.print;
end;
/

Results:

[{
  "ID" : 60150001,
  "DENOUNIDAD" : "Plantio (El)"
}, {
...many lines
...
}, {
  "ID" : 60150033,
  "DENOUNIDAD" : "Pilara (La)"
}]

Code that returns the result of an SQL encapsulated:

  DECLARE
        ret PAQ_TGEOUNIPOBLACIONALES.tipo_TABLA_POBLACIONES;
  BEGIN 

   ret := paq_tgeounipoblacionales.OBTENER_POR_MUNICIPIO ( 6015 );
   FOR indice IN ret.FIRST .. ret.LAST
   LOOP
        DBMS_OUTPUT.put_line ( TO_CHAR( ret (indice).ID ) || ', ' || ret (indice).DENOUNIDAD);
   END LOOP;
  END; 

Results:

60150001, Plantio (El)
...
...
60150033, Pilara (La)

My attempt to encapsulate the call to the function in pljson_dyn:

declare 
  ret json_list;
begin
  ret := json_dyn.executeList( 'paq_tgeounipoblacionales.OBTENER_POR_MUNICIPIO ( 6015 )' );
  ret.print;
end;
Informe de error -
ORA-00900: sentencia SQL no válida
ORA-06512: en "SYS.DBMS_SQL", línea 1120
ORA-06512: en "EDUCOMUNES.JSON_DYN", línea 61
ORA-06512: en línea 4
00900. 00000 -  "invalid SQL statement"
*Cause:    
*Action:

The specification package (simplified) is:

create or replace PACKAGE            PAQ_TGEOUNIPOBLACIONALES
IS
...
    TYPE tipo_TABLA_POBLACIONES IS TABLE OF TGEOUNIPOBLACIONALES%ROWTYPE
    INDEX BY PLS_INTEGER;
...
     FUNCTION OBTENER_POR_MUNICIPIO
     (
     pe_tgeomunicipio_id  IN TGEOMUNICIPIOS.ID%TYPE
     )
     RETURN tipo_TABLA_POBLACIONES;

...    
END PAQ_TGEOUNIPOBLACIONALES;     

The body package (simplified) is:

create or replace PACKAGE BODY            PAQ_TGEOUNIPOBLACIONALES
IS
...

     FUNCTION OBTENER_POR_MUNICIPIO
     (
     pe_tgeomunicipio_id  IN TGEOMUNICIPIOS.ID%TYPE
     )
     RETURN tipo_TABLA_POBLACIONES
     IS       
       l_poblaciones tipo_TABLA_POBLACIONES;       
     BEGIN
        SELECT *
          BULK COLLECT INTO l_poblaciones
          FROM TGEOUNIPOBLACIONALES
         WHERE TGEOMUNICIPIO_ID = pe_tgeomunicipio_id;

        RETURN l_poblaciones;

     END OBTENER_POR_MUNICIPIO;   
...     
END PAQ_TGEOUNIPOBLACIONALES;   

The table structure (simplified) is:

 CREATE TABLE "EDUCOMUNES"."TGEOUNIPOBLACIONALES" 
   (    
    "DENOUNIDAD" VARCHAR2(200 BYTE), 
    "ID" NUMBER(*,0),                     => primary key
    "TGEOMUNICIPIO_ID" NUMBER(*,0)        => foreign key
  ...
  );

Upvotes: 0

Views: 1777

Answers (1)

dsnz
dsnz

Reputation: 415

try the following

(I can't try myself since I don't have a simple and complete test case - including table structure and data - to test, but it should work)

set serveroutput on;
declare 
  ret json_list;
begin
  ret := json_dyn.executeList('select * from table(paq_tgeounipoblacionales.OBTENER_POR_MUNICIPIO ( 6015 ));');  
  ret.print;
end;
/

also I suggest you get the latest pljson version (https://github.com/pljson/pljson/tree/develop_v3)

Upvotes: 0

Related Questions