Oracle
 sql >> Teknologi Basis Data >  >> RDS >> Oracle

ORA-22275:locator LOB tidak valid ditentukan

Ya. LOB adalah penunjuk/referensi ke memori/penyimpanan disk. Anda perlu "memalloc()" (... menginisialisasi) penyimpanan terlebih dahulu, menetapkan pointer/referensi ke variabel LOB Anda. Itulah dbms_lob.createTemporary() adalah untuk. Kecuali Anda menginisialisasi variabel LOB dengan pencari LOB yang valid, semua operasi Anda pada variabel LOB itu akan gagal dengan ORA-22275: invalid LOB locator specified .

Peningkatan: Apakah fungsi PL/SQL Anda di-refactored sedikit:(Dan harap dicatat bahwa saya menggunakan kueri dummy untuk last_60_cpu_cursor kursor. Jangan gunakan kembali kursor, gunakan milik Anda sendiri! :-))

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. Anda tidak perlu membuka+mengambil+menutup kursor. Kursor-loop biasa akan baik-baik saja (jika tidak lebih baik, berkat pengambilan massal implisit di bawah tenda).
  2. Deklarasikan LOB sementara secara eksplisit sebagai cache (cache => true; seperti yang sudah Anda miliki). Ini memastikan potongan data ditambahkan ke LOB di memori, alih-alih ditambahkan pada disk (cache => false ).
  3. Menggabungkan string yang akan ditambahkan ke LOB untuk meminimalkan jumlah panggilan ke dbms_lob.append() .
  4. Hapus dbms_output.put_line() dari fungsi Anda. Jika konten LOB lebih besar dari 32K, ini akan menimbulkan pengecualian.

Juga, setelah Anda selesai mengirimkan LOB kembali ke env Java Anda, membebaskan LOB sementara . (Saya bukan orang Java, tidak bisa menulis potongan kode Java sendiri.)

Juga, Anda memiliki kesalahan konseptual dalam kode Java Anda; mendaftarkan kembalinya fungsi sebagai Types.VARCHAR salah. Anda sebaiknya menggunakan Jenis CLOB khusus Oracle . (Saya telah melihatnya di C#, Java juga harus memilikinya.)

Juga, ada satu masalah kinerja dengan solusi Anda. Fungsi Anda mengembalikan LOB. Dalam PL/SQL, setiap nilai fungsi dikembalikan ke pemanggilnya sebagai salinan dalam dari nilai dalam. Oleh karena itu, jika Anda mengembalikan LOB dari suatu fungsi, konten LOB diduplikasi di latar belakang dengan pencari LOB baru (/ pointer/referensi). Anda harus menggunakan Anda dapat mempertimbangkan untuk menggunakan prosedur tersimpan alih-alih fungsi dan meneruskan LOB ke Java sebagai out nocopy parameter. Proc yang disimpan akan terlihat seperti ini:

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;

Bagaimana tampilan panggilan Java Anda, terserah Anda dan dokumen JDBC ; tetapi, yang pasti, LOB yang dikembalikan dengan cara ini berarti tidak ada konten latar belakang yang disalin. Tentu saja, kebutuhan untuk membebaskan LOB sementara yang dialokasikan tetap berlaku.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Memulai SQL di Oracle Application Express

  2. Bagaimana cara membagi interval antara dua tanggal menjadi detail berdasarkan bulan?

  3. kolom tidak diizinkan di sini kesalahan dalam pernyataan INSERT

  4. Oracle PL/SQL:Buat Paket DML Online

  5. Oracle PL/SQL Bulk Collect With Save Exceptions Contoh