2015-10-16 58 views
7

Mam tabelę w wyroczni z kolumną BLOB, która może przechowywać XMLs i XMLs zip. Są to wymagania klienta i nie można ich zmienić. Tabele zostaną utworzone i muszę przeczytać i pracować z pewnymi informacjami wewnątrz BLOBs.Wstaw ciąg testowy BLOBa większy niż 2000 lub 4000 bajtów

Przeprowadziłem badania i wszelkie niejasne rozwiązania były dla mnie jasne lub sprawdzone.

Problem jestem stoi to, że do INSERTXML zwykły danych większych niż 2000 bytes z utl_raw.cast_to_raw użyciu DBeaver jako menedżera bazy danych. Otrzymałem wiadomość:

SQL Error [6502] [65000]: ORA-06502: PL/SQL: numeric or value error: raw variable length too long ORA-06512: at "SYS.UTL_RAW", line 224 
java.sql.SQLException: ORA-06502: PL/SQL: numeric or value error: raw variable length too long 
ORA-06512: at "SYS.UTL_RAW", line 224 

Problemy

  1. ja zbadali i UTL_RAW nie może być dłuższy niż 2000 bytes
  2. wydaje się, że nie ma innej ograniczenie 4000 bytes dla BLOBs w Oracle

Co mogę zrobić w takich przypadkach?

+0

Co chcesz zrobić? Załadować plik zip do kolumny typu blob? –

+0

Dzięki za zainteresowanie. Problem, przed którym stoję, polega na tym, że WSTAWIĆ zwykłe dane XML większe niż 2000 bajtów za pomocą utl_raw.cast_to_raw – Weslor

+1

Czego używasz do wstawiania danych. SQPLUS lub aplikacja Java? –

Odpowiedz

5

Po pierwsze, musisz zrozumieć, czym są LOB. Są to "duże dane", prawdopodobnie większe niż jakiekolwiek inne typy danych w Oracle. Są jak zwykłe pliki w systemie plików. W celu zapisania pliku na systemem plików, musisz

  1. otworzyć pliku do zapisu
  2. obcina plik, jeśli chcesz rozpocząć wypełnianie go od podstaw
  3. odczytu danych źródłowych kawałeczków w pętli
  4. dołączyć swoje kawałki danych do pliku w tej samej pętli, jeden po drugim
  5. zamknąć plikowi

mniej więcej to samo odnosi się do LOB. W Twojej tabeli kolumna LOB (CLOB/BLOB/NCLOB) jest po prostu wskaźnikiem/odniesieniem do innego miejsca na dysku z danymi rzeczywistymi. W standardowych terminach Oracle wskaźnik nazywany jest "lokalizatorem LOB".Trzeba

  1. otwarty/zainicjować LOB
  2. obciąć zawartości LOB, jeśli chcesz rozpocząć wypełnianie go od podstaw
  3. dołączyć swoje kawałki danych do zawartości LOB w pętli, jeden po drugim
  4. zamknąć lokalizator LOB

W PL/SQL może to wyglądać tak:

-- create table blob_test(id number, b blob); 

declare 
    v_b blob; 
    aaa raw(32767); 
    longLine varchar2(32767); 
begin 
    longLine := LPAD('aaaa', 32767,'x'); 
    aaa := UTL_RAW.CAST_TO_RAW(longLine); 
    insert into blob_test values(1,empty_blob()) returning b into v_b; 
    dbms_lob.open(v_b,dbms_lob.lob_readwrite); 
    dbms_lob.writeappend(v_b,UTL_RAW.LENGTH (aaa) ,aaa); 
    dbms_lob.close(LOB_LOC=>v_b); 
    commit; 
end; 

Wyjaśnienie:

  1. zainicjować lokalizator LOB = insert into blob_test values(1,empty_blob()) returning b into v_b;
  2. otworzyć lokalizator LOB do pisania = dbms_lob.open(v_b,dbms_lob.lob_readwrite);
  3. obciąć zawartości LOB, jeśli chcesz rozpocząć wypełnianie go od nowa ... To odbywa się przez wywołanie empty_blob() w insert.
  4. dołączyć swoje kawałki danych do zawartości LOB w pętli, jeden po drugim = tutaj tylko jednej iteracji dbms_lob.writeappend(), dołączając tylko jeden klocek aaa długości utl_raw.length(aaa) (maksymalnie 32767) do LOB v_b
  5. zamknąć LOB locator = dbms_lob.close(LOB_LOC=>v_b);
+0

Nie rozumiem tego i nie wiem, w jaki sposób mam go używać. Czy mógłbyś wyjaśnić, w jaki sposób mam użyć tego skryptu, aby go uwzględnić w moim własnym skrypcie, który ma wiele wstawek, w przypadku na przykład mój stół nazywa się "MYTABLE" i chcę wstawić ciąg lub XML z 5000 znaków, jak by to wyglądało? – Weslor

+0

*) Informacje o oracle direcroty i BFILENAME [Info ] (http://www.techonthenet.com/oracle/functions/bfilename.php) *) Załaduj plik [przykład] (http://www.anujparashar.com/blog/loading-text-file-into-clob -field-in-oracle) 1) Skopiuj swój xml do serwera oracle_server. 2) Utwórz katalog Oracle. 3) Przekaż dostęp do katalogu. 4) Wykonaj przykład. –

+0

Przypadki użycia dla operacji LOB są zbytnio zależne od faktycznego miejsca pobytu samej manipulacji. Ta odpowiedź dobrze dostarcza ogólnego przykładu, resztę powinno się opierać na zdolnościach samokształcenia OP. – nop77svk

-1

Funkcja utl_raw.cast_to_raw konwertuje wartość typu danych VARCHAR2 na wartość nieprzetworzoną. Oczywiście długość łańcucha jest ograniczona typem danych VARCHAR2. Jeśli potrzebujesz konwertować duże dane tekstowe na LOB, możesz użyć procedury DBMS_LOB.CONVERTTOBLOB.

Na przykład można utworzyć funkcję do konwersji dużej wartości ciągu (clob jako dane wejściowe) na obiekt typu blob. coś takiego -

create or replace function ClobToBlob (p_clob in clob) return blob is 
    l_dest_offset integer := 1; 
    l_source_offset integer := 1; 
    p_csid   number := 0; 
    l_lang_context integer := DBMS_LOB.DEFAULT_LANG_CTX; 
    l_warning  integer := DBMS_LOB.WARN_INCONVERTIBLE_CHAR; 
    l_tmpblob blob; 

    begin 
    dbms_lob.createtemporary(l_tmpblob, true); 
    DBMS_LOB.CONVERTTOBLOB 
    (
    l_tmpblob, 
    p_clob, 
    DBMS_LOB.LOBMAXSIZE, 
    l_dest_offset, 
    l_source_offset, 
    p_csid, 
    l_lang_context, 
    l_warning 
); 
    return l_tmpblob; 
end;