2017-11-03 151 views
10

1) Mam zrobić json z kwerendy wybierz Oracle, który ma trzy podejścia, które można wykonać.Jak wygenerować JSON w Oracle dla CLOB, który jest> 32k (na przykład 60 000 znaków)?

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

również próbowałem z tym podejściem

2) Jeśli nie jesteś w stanie załatać/praca z tej wersji jest doskonały pakiet napisany przez Lewisa Cunningham i Jonas Krogsboell: PL/JSON * http://pljson.sourceforge.net/

To doskonały pakiet (użyłem go w wielu instalacjach baz danych).

Zawarte przykłady są dobre i obejmują większość scenariuszy.

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

Wzmianka W tej odpowiedzi też nie działa na tak duży clob. Return results of a sql query as JSON in oracle 12c

3) Inne podejście może być możemy złączyć ciąg po kwerendy wybierającej.

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 podejście rozwiązać mój problem, ale nie chcę, aby uruchomić dla pętli. Czy jest jakieś rozwiązanie w wyroczni, żeby sobie z tym poradzić?

Sprawdzam rozwiązanie, ale to nie działa bez pętli for.

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

url ma zapewnić pewne rozwiązanie, próbowałem tego, ale nie działa .Same problem nadchodzi.

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

Could jesteś w stanie mi powiedzieć, w jaki sposób można to zrobić?

+0

Jaka jest wersja bazy danych, w tym przypadku? Oracle 12c (12.1.0.2) ma natywny typ danych json, który może rozwiązać twój problem (https://docs.oracle.com/database/121/ADXDB/json.htm). Istnieje również parametr DB MAX_STRING_SIZE, który można ustawić na EXTENDED (daje 32k zmiennych VARCHAR2). Dlaczego wszystkie te informacje dla: W Oracle Database, dane JSON są przechowywane przy użyciu wspólnych typów danych SQL VARCHAR2, CLOB i BLOB (sprawdź to: https://docs.oracle.com/database/122/ADJSN/json-in- oracle-database.htm # ADXDB6371). – g00dy

+0

Błąd, który stwierdza się, że parametr MAX_STRING_SIZE jest ustawiony na STANDARD i próbujesz przekonwertować obiekt CLOB (4 GB) na VARCHAR2 (który jest 4000b) w twoim przypadku. Jeśli potrzebujesz czegoś podobnego do 60k, nie możesz użyć VARCHAR2, ale tylko CLOB, czyli jeśli chcesz mieć całe dane w jednej zmiennej. – g00dy

Odpowiedz

7

W odpowiedzi na to pytanie:

3 podejście rozwiązać mój problem, ale nie chcę, aby uruchomić dla pętli. Czy jest jakieś rozwiązanie w wyroczni, żeby sobie z tym poradzić?

Struny mogą być łączone bez zapętlenie za pomocą LISTAGG funkcji Oracle:

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

Jednakże, jak już wskazano w komentarzach, LISTAGG ma limit 4000 znaków. Poniżej bardziej złożone/skomplikowanego ale należy sprostać poza ten limit:

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 uchwyty CLOB s lecz funkcja EXTRACT ma efekt uboczny ucieczki pewnych znaków (na przykład z " do &quot;). Powyższe zapytanie przekształca je z powrotem (np.od &quot; do ") za pomocą funkcji dbms_xmlgen.convert - więcej informacji na ten temat można znaleźć w artykule this answer.

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

+0

Nie, to nie jest rozwiązanie. sprawdź to zapytanie w wyroczni, co daje błąd.ORA-22835: Zbyt mały bufor dla CLOB do konwersji typu CHAR lub BLOB na RAW (rzeczywisty: 57416, maksimum: 4000) –

+0

Zmieniono moją odpowiedź - proszę dać mi znać, czy nowa metoda działa ... –

+0

To też nie działa, ten sam problem. –

0

Można powiedzieć Oracle, aby powrócić CLOB zamiast varchar2 (4000):

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