web-dev-qa-db-fra.com

Renvoie les résultats d'une requête SQL en tant que JSON dans Oracle 12c

Contexte

J'ai besoin d'extraire quelques milliers de lignes d'Oracle et de les convertir en JSON pour pouvoir les utiliser dans SlickGrid. Actuellement, je récupère les lignes en PHP, je les convertis de ISO à UTF-8 avec iconv et je les exporte au format json avec json_encode. L'ensemble de l'opération prend environ 1 seconde du côté de la base de données et 5 secondes pour générer du JSON. C'est trop long.

La question

J'ai lu qu'Oracle 12c prend en charge JSON, mais je ne trouve pas exactement ce dont j'ai besoin.

Existe-t-il un moyen de renvoyer le résultat d'une requête SQL standard au format JSON?

supposément je voudrais émettre une requête semblable à ceci:

SELECT * from table AS JSON

et recevez un json valide semblable à ceci: 

[{"col1": "value1", "col2": 2}, {"col1": "valueOfRow2", "col2": 3}]

Une chose importante est que je dois avoir échappé les séquences unicode, car j'utilise le jeu de caractères ISO-8859-2 du côté client, et que JSON doit être en UTF-8 ou avoir les séquences échappées.

20
SWilk

Oracle 12c version 12.1.0.2 (la dernière version en date du 11.11.2014) ajoute le support JSON: https://docs.Oracle.com/database/121/NEWFT/chapter12102.htm#BGBGADCC

Il est disponible depuis le 17 octobre. https://blogs.Oracle.com/db/entry/Oracle_database_12c_release_1

Si vous ne parvenez pas à corriger/utiliser cette version, il existe un excellent package écrit par Lewis Cunningham et Jonas Krogsboell: PL/JSON * http://pljson.sourceforge.net/

C'est un excellent package (je l'ai utilisé dans de nombreuses installations de bases de données).

Les exemples fournis sont bons et couvrent la plupart des scénarios. 

declare 
  ret json;
begin
  ret := json_dyn.executeObject('select * from tab');
  ret.print;
end;
/
15
Olafur Tryggvason

12cR2 (disponible dans le nuage Oracle) le prend en charge de manière native.

SQL> select JSON_ARRAY(EMPLOYEE_ID, FIRST_NAME,LAST_NAME) from HR.EMPLOYEES;

JSON_ARRAY(EMPLOYEE_ID,FIRST_NAME,LAST_NAME)
--------------------------------------------------------------------------------
[100,"Steven","King"]
[101,"Neena","Kochhar"]

ou 

SQL> select JSON_OBJECT('ID' is EMPLOYEE_ID , 'FirstName' is FIRST_NAME,'LastName' is LAST_NAME) from HR.EMPLOYEES;

JSON_OBJECT('ID'ISEMPLOYEE_ID,'FIRSTNAME'ISFIRST_NAME,'LASTNAME'ISLAST_NAME)
----------------------------------------------------------------------------
{"ID":100,"FirstName":"Steven","LastName":"King"}
{"ID":101,"FirstName":"Neena","LastName":"Kochhar"}
6
mark d drake

Vous pouvez utiliser xmltype pour convertir le résultat d'un SQL en XML et JSON. Voir l'article suivant pour connaître la solution qui fonctionnera pour Oracle depuis la version 9. Vous pouvez également télécharger le package itstar_xml_util: 

http://stefan-armbruster.com/index.php/12-it/pl-sql/12-Oracle-xml-and-json-goodies

Un exemple simple avec la table emp:

declare
  l_sql_string varchar2(2000);
  l_xml        xmltype;
  l_json       xmltype;
begin
  l_sql_string := 'select a.empno, a.ename, a.job from emp a';

  -- Create the XML aus SQL
  l_xml := itstar_xml_util.sql2xml(l_sql_string);

  -- Display the XML
  dbms_output.put_line(l_xml.getclobval());

  l_json := itstar_xml_util.xml2json(l_xml);
  -- Display the JSON
  dbms_output.put_line(l_json.getclobval());  
end;

Le résultat ressemble à ceci:

{"ROWSET": [
    {
      "EMPNO": 7839,
      "ENAME": "KING",
      "JOB": "PRESIDENT"
    },
    {
      "EMPNO": 7698,
      "ENAME": "BLAKE",
      "JOB": "MANAGER"
    },
[...]
    {
      "EMPNO": 7934,
      "ENAME": "MILLER",
      "JOB": "CLERK"
    }
  ]}
4
PT_STAR

La prise en charge de JSON par Oracle 12c permet de stocker des objets JSON, de les interroger et de les sélectionner.

Vous avez un format de tableau et vous devez uniquement afficher vos données sous forme de fichier JSON. Ainsi, vous pouvez simplement concaténer des lignes dans {'col1': 'rowN1', 'col2': 'rowN2'} et faire le reste côté client ..__ ou vous pouvez utiliser LISTAGG pour obtenir le document entier. Exemple: http://technology.amis.nl/2011/06/14/creating-json-document-straight-from-sql-query-using-listagg-and-with-clause/

Faites attention à la limite SQL VARCHAR2 de 4000 caractères.

Vous pouvez également consulter http://database-geek.com/2009/03/25/json-in-and-out-of-Oracle-json-data-type/ Mais je ne pense pas, Ce type d'objet Oracle améliorera vos performances.

Une autre approche consiste à exporter XML en utilisant XMLType. Puis convertissez XML en JSON. XMLType prend en charge les caractères spéciaux et l'API est assez stable (vous n'aurez pas besoin de réécrire votre programme pour Oracle 14).

1
vav

Pour ajouter à la réponse dans Oracle 12.2, vous pouvez créer un json comme vous le souhaitez.

SELECT JSON_ARRAY(
JSON_OBJECT (
         KEY 'number' VALUE s.number,
         KEY 'name' VALUE s.sname,
         KEY 'location' VALUE s.loc
          )
       ) AS student_det
FROM   student s;
1
Himanshu sharma

Essayez ceci:

:) la vie est heureuse

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
Shahbaz Ali