如何在Oracle中为CLOB生成JSON> 32k(例如60,000个字符)?

时间:2017-11-03 09:54:18

标签: sql json oracle plsql clob

1)我必须从oracle select query中创建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;
/

提及在这个答案中,但不适用于这样的大事。 Return results of a sql query as JSON in oracle 12c

3)另一种方法是我们可以在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方法解决了我的问题,但我不想运行循环。 oracle中是否有任何解决方案可以解决这个问题。

我检查了解决方案,但是没有for循环就无法工作。

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

url已经提供了一些解决方案,我试过这个但是没有用.Same问题即将到来。

  

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

你能告诉我怎么做吗?

3 个答案:

答案 0 :(得分:8)

回答这个问题:

  

3方法解决了我的问题,但我不想运行循环。 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,但EXTRACT函数具有转义某些字符(例如从"&quot;)的副作用。上面的查询使用&quot;函数将这些转换回来(例如从"转换为dbms_xmlgen.convert) - 有关详细信息,请参阅this answer

SQL小提琴演示: http://sqlfiddle.com/#!4/5b295/40

答案 1 :(得分:0)

  

默认情况下,新的json_ *函数返回varchar2(4000)。您可以在returning子句中对此进行更改。

     

如果启用了扩展数据类型,则可以将其更改为varchar2(32767)。但是只有* agg函数支持clob。

来自here

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 *函数中的Clobs

答案 2 :(得分:0)

在12.2中,json_ *函数可以很好地处理Clob。 Use子句返回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;