Oracle
 sql >> база данни >  >> RDS >> Oracle

ORA-22275:указан е невалиден LOB локатор

да LOB е указател/препратка към памет/диск за съхранение. Първо трябва да "memalloc()" (... инициализирате) хранилището, да присвоите указателя/препратката към вашата LOB променлива. Това е, което dbms_lob.createTemporary() е за. Освен ако не инициализирате LOB променлива с валиден LOB локатор, всички ваши операции върху тази LOB променлива ще се провалят с ORA-22275: invalid LOB locator specified .

Подобрение: Преработете малко вашата PL/SQL функция:(И моля, обърнете внимание, че използвах фиктивна заявка за last_60_cpu_cursor курсор. Не използвайте повторно курсора, използвайте свой собствен! :-))

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. Не е необходимо да отваряте+извличате+затваряте курсора. Обикновен цикъл на курсора ще се справи добре (ако не и по-добре, благодарение на имплицитното групово извличане под капаците).
  2. Изрично декларирайте временния LOB като кеширан (cache => true; както вече имате). Това гарантира, че частите от данни се добавят към LOB в паметта, вместо да се добавят на диска (cache => false ).
  3. Свържете низовете, които ще бъдат добавени към LOB, така че да минимизирате броя на извикванията към dbms_lob.append() .
  4. Премахнете dbms_output.put_line() от вашата функция. В случай на LOB съдържание, по-голямо от 32K, това така или иначе ще предизвика изключение.

Освен това, след като приключите с доставянето на LOB обратно във вашата Java среда, освободете временния LOB . (Не съм Java човек, не мога сам да напиша кодовия фрагмент на Java.)

Освен това имате концептуална грешка във вашия Java код; регистриране на връщането на функцията като Types.VARCHAR не е наред. По-скоро трябва да използвате специалния CLOB тип на Oracle . (Виждал съм ги в C#, Java също трябва да ги има.)

Освен това има един проблем с производителността на вашето решение. Вашата функция връща LOB. В PL/SQL всяка стойност на функцията се връща на извикващия я като дълбоко копие на вътрешната стойност. Следователно, ако върнете LOB от функция, LOB съдържанието се дублира във фонов режим с нов LOB локатор (/указател/референция). Трябва да използвате Може да обмислите използването на съхранена процедура вместо функция и да предадете LOB на Java като out nocopy параметър. Тогава съхранената процедура ще изглежда така:

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;

Как ще изглежда вашето Java обаждане, зависи от вас и JDBC документ ; но със сигурност LOB, върнат по този начин, би означавал липса на копиране на фоново съдържание. Разбира се, необходимостта от освобождаване на разпределения временен 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. Как да използвам sql*plus в командния скрипт на Windows за управление на потока?

  2. Dynamic Select SQL изрази с MyBatis

  3. Разбиране на резултатите от Execute Explain Plan в Oracle SQL Developer

  4. Как да премахна дубликати от listagg

  5. Oracle InvalidOperationException - При опит за избор от таблица