web-dev-qa-db-fra.com

Comment générer du JSON dans Oracle pour un CLOB de plus de 32 000 caractères (par exemple 60 000 caractères)?

1) Je dois faire une requête de sélection JSON à partir de Oracle qui a trois approches que je peux suivre.

SELECT JSON_ARRAY(json_object('id'         VALUE employee_id, 
                   'data_clob'    VALUE data_clob
                     )) from tablename;

aussi j'ai essayé avec cette approche

2) 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;
/

Mention Dans cette réponse aussi mais ne fonctionne pas pour un tel gros clob. Renvoie les résultats d'une requête SQL en tant que JSON dans Oracle 12c

3) L'autre approche peut être que nous pouvons concaténer la chaîne après la requête select.

FOR rec IN (SELECT employee_id, data_clob
                FROM tablename) LOOP
      IF i <> 1 THEN
        v_result := v_result || ',';
      END IF;

      v_result := v_result || '{"employee_id":' || to_char(rec.employee_id) || ',"data_clob": ' || rec.data_clob || '}';

      i := i + 1;
    END LOOP;
    v_result := v_result || ']}'; 

3 approche résoudre mon problème mais je ne veux pas courir pour boucle . Existe-t-il une solution dans Oracle pour gérer cela?.

Je vérifie la solution, mais cela ne fonctionne pas sans boucle.

https://technology.amis.nl/2015/03/13/using-an-aggregation-function-to-query-a-json-string-straing-from-sql/

url a fourni une solution, j’ai essayé mais cela ne fonctionne pas. Le même problème est imminent.

ORA-22835: Buffer too small for CLOB to CHAR or BLOB to RAW conversion (actual: 57416, maximum: 4000)

Pouvez-vous me dire comment cela peut être fait?

12
Himanshu sharma

En réponse à cette question:

3 approche résoudre mon problème mais je ne veux pas courir pour la boucle. Existe-t-il une solution dans Oracle pour gérer cela?.

Les chaînes peuvent être concaténées sans boucle en utilisant la fonction LISTAGG de Oracle:

SELECT '{"employees":[' || LISTAGG('{"employee_id":' || to_char(employee_id)
                      || ',"data_clob":"' || data_clob || '"}', ',')
              WITHIN GROUP (ORDER BY employee_id) || ']}' AS json
FROM tablename;

Toutefois, comme vous l'avez indiqué dans les commentaires, la variable LISTAGG est limitée à 4 000 caractères. Ce qui suit est plus complexe/fastidieux, mais devrait faire face à cette limite:

SELECT '{"employees":[' || dbms_xmlgen.convert(
         RTRIM(XMLAGG(XMLELEMENT(E,'{"employee_id":' || to_char(employee_id)
                                 || ',"data_clob":"' || data_clob || '"}',',')
                      .EXTRACT('//text()') ORDER BY employee_id).GetClobVal(),',')
       , 1) || ']}' AS json
FROM tablename;

XMLAGG gère CLOBs mais la fonction EXTRACT a pour effet secondaire d'échapper à certains caractères (par exemple de " à &quot;). La requête ci-dessus reconvertit ces informations (par exemple, de &quot; à ") à l'aide de la fonction dbms_xmlgen.convert - voir cette réponse pour plus de détails.

Démonstration de SQL Fiddle:http://sqlfiddle.com/#!4/5b295/40

8
Steve Chambers

Par défaut, les nouvelles fonctions json_ * renvoient un varchar2 (4000). Vous pouvez changer cela dans la clause de retour.

Si les types de données étendus sont activés, vous pouvez le remplacer par varchar2 (32767). Mais seules les fonctions * agg supportent clob. 

de ici

SELECT length(JSON_ARRAYAGG( 
         JSON_OBJECT( 
           KEY 'object_type' VALUE object_type, 
           KEY 'object_name' VALUE object_name 
         ) 
       returning clob) 
       ) array_size
FROM   all_objects;

ARRAY_SIZE  
5772072  

18c prend également en charge les éléments dans les fonctions JSON * 

0
Toolkit