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ループなしでは機能しません。
uRLはいくつかの解決策を提供しています、私はこれを試しましたが機能しません。
ORA-22835: Buffer too small for CLOB to CHAR or BLOB to RAW conversion (actual: 57416, maximum: 4000)
どうすればできるか教えてもらえますか?
この質問に答えて:
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;
XMLAGG
はCLOB
sを処理しますが、 EXTRACT
関数は特定の文字をエスケープするという副作用があります(例:"
〜"
)。上記のクエリはこれらを元に変換します(例:"
〜"
)dbms_xmlgen.convert
関数-詳細は この答え を参照してください。
SQL Fiddle demo:http://sqlfiddle.com/#!4/5b295/4
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;
デフォルトでは、新しい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も完全にサポートしています。