web-dev-qa-db-ja.com

32Kを超えるCLOB(例:60,000文字)のOracleでJSONを生成するにはどうすればよいですか?

1)私が従うことができる3つのアプローチを持つOracle選択クエリからjsonを作成する必要があります。

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

また、私はこのアプローチで試しました

2)そのバージョンでパッチ/作業できない場合は、Lewis CunninghamとJonas Krogsboellによって書かれた優れたパッケージがあります:PL/JSON *- http://pljson.sourceforge.net/

これは優れたパッケージです(私は数多くのデータベースインストールで使用しています)。

含まれている例は適切で、ほとんどのシナリオをカバーしています。

_declare 
  ret json;
begin
  ret := json_dyn.executeObject('select * from tab');
  ret.print;
end;
/
_

この回答でも言及しますが、そのような大きな塊では機能しません。 SQLクエリの結果をOracle 12cのJSONとして返す

3)他のアプローチとして、選択クエリの後に文字列を連結することができます。

_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アプローチは私の問題を解決しますが、for loopを実行したくありません。 Oracleでこれを処理するためのソリューションはありますか。

私は解決策をチェックしますが、それはforループなしでは機能しません。

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

uRLはいくつかの解決策を提供しています、私はこれを試しましたが機能しません。

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

どうすればできるか教えてもらえますか?

12
Himanshu sharma

この質問に答えて:

3アプローチは私の問題を解決しますが、for loopを実行したくありません。これを処理するOracleのソリューションはありますか。

Oracleの LISTAGG 関数を使用すると、ループせずに文字列を連結できます。

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

ただし、コメントで指摘したように、LISTAGGには4000文字の制限があります。以下はより複雑/手間がかかりますが、この制限を超えて対処する必要があります:

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;

XMLAGGCLOBsを処理しますが、 EXTRACT 関数は特定の文字をエスケープするという副作用があります(例:"&quot;)。上記のクエリはこれらを元に変換します(例:&quot;"dbms_xmlgen.convert関数-詳細は この答え を参照してください。

SQL Fiddle demo:http://sqlfiddle.com/#!4/5b295/4

8
Steve Chambers

12.2では、json_ *関数はCLOBを適切に処理します。 Use句Returning CLOB

create table t( c clob, constraint t_chk check (c is json));
declare
    v_clob clob;
begin
    for i in 1..10000 loop
        v_clob := v_clob || 'asdasdadasdasdasdasdasdasdasd';
    end loop;

    insert into t(c) 
    select 
        json_object
        (
           'body' value v_clob returning clob
         )
    from
        dual;
end;   
0
Brzl

デフォルトでは、新しいjson_ *関数はvarchar2(4000)を返します。これは、returning句で変更できます。

拡張データ型を有効にしている場合は、これをvarchar2(32767)に変更できます。ただし、* agg関数のみがclobをサポートします。

から ここ

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は、JSON *関数のCLOBも完全にサポートしています。

0
Toolkit