Oracle
 sql >> Baza danych >  >> RDS >> Oracle

ORA-22275:określono nieprawidłowy lokalizator LOB

TAk. LOB jest wskaźnikiem/odniesieniem do pamięci/dysku. Musisz najpierw "memalloc()" (... zainicjować) pamięć, przypisać wskaźnik/odwołanie do zmiennej LOB. To właśnie dbms_lob.createTemporary() jest dla. O ile nie zainicjujesz zmiennej LOB z prawidłowym lokalizatorem LOB, wszystkie operacje na tej zmiennej LOB zakończą się niepowodzeniem z ORA-22275: invalid LOB locator specified .

Ulepszenie: Zrefaktoruj nieco swoją funkcję PL/SQL:(proszę zauważyć, że użyłem fikcyjnego zapytania dla last_60_cpu_cursor kursor. Nie używaj ponownie kursora, użyj własnego! :-))

create or replace
function statistics_function
    ( namein                        in varchar2 )
    return clob
is
    line                            clob;
    cursor last_60_cpu_cursor       is
        select 1 as last_60_cpu, sysdate as last_60_event_date
        from dual
    ;
begin
    dbms_lob.createtemporary(lob_loc => line, cache => true, dur => dbms_lob.call);

    for cv in last_60_cpu_cursor loop
        dbms_lob.append(line, to_char(cv.last_60_event_date)||'i'||to_char(cv.last_60_cpu)||chr(10));
    end loop;

    dbms_lob.append(line, 'last_60_cpu'||chr(10));

    return line;
end statistics_function;
  1. Nie musisz otwierać+pobierać+zamykać kursora. Zwykła pętla kursora wystarczy (jeśli nie lepiej, dzięki niejawnemu pobieraniu zbiorczemu pod maskami).
  2. Jawnie zadeklaruj tymczasowy obiekt LOB jako buforowany (cache => true; jak już masz). Zapewnia to dodawanie porcji danych do LOB w pamięci, zamiast na dysku (cache => false ).
  3. Połącz ciągi, które mają być dołączone do LOB, aby zminimalizować liczbę wywołań dbms_lob.append() .
  4. Usuń dbms_output.put_line() z twojej funkcji. W przypadku zawartości LOB większej niż 32 KB i tak spowoduje to zgłoszenie wyjątku.

Ponadto, gdy zakończysz dostarczanie LOB z powrotem do środowiska Java, uwolnij tymczasowy LOB . (Nie jestem facetem od Javy, nie mogę sam napisać fragmentu kodu Java.)

Ponadto masz błąd koncepcyjny w kodzie Java; rejestracja zwrotu funkcji jako Types.VARCHAR jest źle. Powinieneś raczej użyć dedykowanego typu CLOB Oracle . (Widziałem je w C#, Java też musi je mieć.)

Ponadto istnieje jeden problem z wydajnością Twojego rozwiązania. Twoja funkcja zwraca LOB. W PL/SQL każda wartość funkcji jest zwracana do jej wywołującego jako głęboka kopia wartości wewnętrznej. W związku z tym, jeśli zwracasz LOB z funkcji, zawartość LOB jest duplikowana w tle z nowym lokalizatorem LOB (/pointer/reference). Powinieneś użyć Możesz rozważyć użycie procedury składowanej zamiast funkcji i przekazać LOB do Javy jako out nocopy parametr. Zapisany proces wyglądałby wtedy tak:

create or replace
procedure statistics_function
    ( namein                        in varchar2
    , lob_out                       out nocopy clob )
is
    cursor last_60_cpu_cursor       is
        select 1 as last_60_cpu, sysdate as last_60_event_date
        from dual
    ;
begin
    dbms_lob.createtemporary(lob_loc => lob_out, cache => true, dur => dbms_lob.session);

    for cv in last_60_cpu_cursor loop
        dbms_lob.append(lob_out, to_char(cv.last_60_event_date)||'i'||to_char(cv.last_60_cpu)||chr(10));
    end loop;

    dbms_lob.append(lob_out, 'last_60_cpu'||chr(10)||chr(10));
end statistics_function;

Jak będzie wyglądać Twoje wywołanie Java, zależy od Ciebie i Dokument JDBC ; ale na pewno LOB zwrócony w ten sposób oznaczałby brak kopiowania zawartości w tle. Oczywiście nadal obowiązuje potrzeba zwolnienia przydzielonego tymczasowego LOB.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Deklaracja wielu wartości w zmiennych Oracle BIND

  2. Używanie 'kolumny wyrażenia przypadku' w klauzuli where

  3. ORA-12516, TNS:listener nie mógł znaleźć dostępnej obsługi

  4. pobierz nazwę tabeli z kolumny dla klauzuli from

  5. Jak sprawić, by SQL*Plus tworzył widoki/tabele z pustą linią w środku instrukcji create?