it-swarm-id.com

Apa perbedaan antara kursor eksplisit dan implisit dalam Oracle?

Saya agak berkarat pada istilah kursor saya di PL/SQL. Adakah yang tahu ini?

25
Brian G

Kursor implisit adalah kursor yang dibuat "secara otomatis" untuk Anda oleh Oracle ketika Anda menjalankan kueri. Lebih mudah untuk kode, tetapi menderita 

  • inefisiensi (standar ANSI menetapkan bahwa ia harus mengambil dua kali untuk memeriksa apakah ada lebih dari satu catatan)
  • kerentanan terhadap kesalahan data (jika Anda pernah mendapatkan dua baris, itu menimbulkan pengecualian TOO_MANY_ROWS)

Contoh

SELECT col INTO var FROM table WHERE something;

Kursor eksplisit adalah kursor yang Anda buat sendiri. Dibutuhkan lebih banyak kode, tetapi memberi lebih banyak kontrol - misalnya, Anda bisa buka-ambil-tutup jika Anda hanya ingin catatan pertama dan tidak peduli jika ada yang lain. 

Contoh

DECLARE   
  CURSOR cur IS SELECT col FROM table WHERE something; 
BEGIN
  OPEN cur;
  FETCH cur INTO var;
  CLOSE cur;
END;
39
Sten Vesterli

Kursor eksplisit didefinisikan seperti itu di blok deklarasi:

DECLARE 
CURSOR cur IS 
  SELECT columns FROM table WHERE condition;
BEGIN
...

kursor implisit diimplikasikan langsung dalam blok kode:

...
BEGIN
   SELECT columns INTO variables FROM table where condition;
END;
...
16
stjohnroe

1.CURSOR: Ketika PLSQL mengeluarkan pernyataan sql itu menciptakan area kerja pribadi untuk mengurai & menjalankan pernyataan sql disebut kursor.

2. SIMPLIKIT: Ketika ada blok PL/SQLexecutable mengeluarkan pernyataan sql . PL/SQL menciptakan kursor implisit dan mengelola secara otomatis berarti buka & tutup implisit terjadi. Ini digunakan ketika pernyataan sql kembali hanya satu baris. Ini memiliki 4 atribut SQL% ROWCOUNT, SQL% FOUND, SQL% NOTFOUND, SQL% ISOPEN.

3. EXPLICIT: Ini dibuat & dikelola oleh programmer. Perlu setiap waktu eksplisit terbuka, ambil & tutup. Ini digunakan ketika pernyataan sql mengembalikan lebih dari satu baris. Ini juga memiliki 4 atribut CUR_NAME% ROWCOUNT, CUR_NAME% FOUND, CUR_NAME% NOTFOUND, CUR_NAME% ISOPEN. Ini memproses beberapa baris dengan menggunakan loop. Pemrogram dapat meneruskan parameter juga ke kursor eksplisit.

  • Contoh: Kursor Eksplisit

declare 
   cursor emp_cursor 
   is 
   select id,name,salary,dept_id 
   from employees; 
   v_id employees.id%type; 
   v_name employees.name%type; 
   v_salary employees.salary%type; 
   v_dept_id employees.dept_id%type; 
   begin 
   open emp_cursor; 
   loop 
   fetch emp_cursor into v_id,v_name,v_salary,v_dept_id; 
   exit when emp_cursor%notfound;
   dbms_output.put_line(v_id||', '||v_name||', '||v_salary||','||v_dept_id); 
   end loop;                    
   close emp_cursor; 
   end;
4
Ganesh Pathare

Kursor implisit membutuhkan memori buffer anonim. 

Kursor eksplisit dapat dieksekusi berulang kali dengan menggunakan namanya. Mereka disimpan dalam ruang memori yang ditentukan pengguna daripada disimpan dalam memori buffer anonim dan karenanya dapat dengan mudah diakses setelahnya.

3
prince
3
pablo

Kursor eksplisit adalah kursor yang Anda nyatakan, seperti:

CURSOR my_cursor IS
  SELECT table_name FROM USER_TABLES

Kursor implisit adalah kursor yang dibuat untuk mendukung SQL in-line yang Anda tulis (statis atau dinamis).

3
Dave Costa

Sebagai jawaban atas pertanyaan pertama. Langsung dari Oracle dokumentasi

Kursor adalah pointer ke SQL pribadi area yang menyimpan informasi tentang memproses SELECT atau DML .__ tertentu. pernyataan.

3
Ian Carpenter

Dengan kursor eksplisit, Anda memiliki kontrol penuh atas cara mengakses informasi dalam database. Anda memutuskan kapan harus BUKA kursor, kapan akan FETCH catatan dari kursor (dan karenanya dari tabel atau tabel dalam pernyataan SELECT kursor) berapa banyak catatan untuk diambil, dan kapan harus TUTUP kursor. Informasi tentang keadaan kursor Anda saat ini tersedia melalui pemeriksaan atribut kursor.

Lihat http://www.unix.com.ua/orelly/Oracle/prog2/ch06_03.htm untuk detailnya.

2
Kristian

Kursor adalah jendela yang dipilih pada tabel Oracle, ini berarti sekelompok catatan hadir dalam tabel Oracle, dan memenuhi kondisi tertentu. Kursor juga dapat MEMILIH semua konten tabel. Dengan kursor, Anda dapat memanipulasi kolom Oracle, alias menambahkannya di hasilnya. Contoh kursor implisit adalah sebagai berikut:

BEGIN
   DECLARE
      CURSOR C1
      IS
         SELECT DROPPED_CALLS FROM ALARM_UMTS;

      C1_REC   C1%ROWTYPE;
   BEGIN
      FOR C1_REC IN C1
      LOOP
         DBMS_OUTPUT.PUT_LINE ('DROPPED CALLS: ' || C1_REC.DROPPED_CALLS);
      END LOOP;
   END;
END;
/

Dengan FOR ... LOOP ... END LOOP Anda membuka dan menutup kursor secara otomatis, ketika semua catatan kursor dianalisis.

Contoh kursor eksplisit adalah sebagai berikut:

BEGIN
   DECLARE
      CURSOR C1
      IS
         SELECT DROPPED_CALLS FROM ALARM_UMTS;

      C1_REC   C1%ROWTYPE;
   BEGIN
      OPEN c1;

      LOOP
         FETCH c1 INTO c1_rec;

         EXIT WHEN c1%NOTFOUND;

         DBMS_OUTPUT.PUT_LINE ('DROPPED CALLS: ' || C1_REC.DROPPED_CALLS);
      END LOOP;

      CLOSE c1;
   END;
END;
/

Di kursor eksplisit Anda membuka dan menutup kursor dengan cara eksplisit, memeriksa keberadaan catatan dan menyatakan kondisi keluar.

1
UltraCommit

Google adalah teman Anda: http://docstore.mik.ua/orelly/Oracle/prog2/ch06_03.htm

PL/SQL mengeluarkan kursor implisit setiap kali Anda menjalankan pernyataan SQL langsung dalam kode Anda, selama itu kode tidak menggunakan kursor. Ini disebut "implisit" kursor karena Anda, pengembang, lakukan tidak secara eksplisit mendeklarasikan kursor untuk pernyataan SQL.

Kursor eksplisit adalah SELECT pernyataan yang secara eksplisit didefinisikan di bagian deklarasi .__ Anda. kode dan, dalam proses, ditugaskan a nama. Tidak ada yang namanya kursor eksplisit untuk UPDATE, DELETE, dan pernyataan INSERT.

1
Derek Swingley

Kursor implisit mengembalikan hanya satu catatan dan dipanggil secara otomatis. Namun, kursor eksplisit dipanggil secara manual dan dapat mengembalikan lebih dari satu catatan.

1
shaiksyedbasha

Saya tahu ini adalah pertanyaan lama, namun, saya pikir akan bagus untuk menambahkan contoh praktis untuk menunjukkan perbedaan antara keduanya dari sudut pandang kinerja.

Dari sudut pandang kinerja, kursor implisit lebih cepat.

Mari kita lihat perbedaan kinerja antara keduanya:

SQL> SET SERVEROUTPUT ON
SQL> DECLARE
  2    l_loops  NUMBER := 100000;
  3    l_dummy  dual.dummy%TYPE;
  4    l_start  NUMBER;
  5
  6    CURSOR c_dual IS
  7      SELECT dummy
  8      FROM   dual;
  9  BEGIN
 10    l_start := DBMS_UTILITY.get_time;
 11
 12    FOR i IN 1 .. l_loops LOOP
 13      OPEN  c_dual;
 14      FETCH c_dual
 15      INTO  l_dummy;
 16      CLOSE c_dual;
 17    END LOOP;
 18
 19    DBMS_OUTPUT.put_line('Explicit: ' ||
 20                         (DBMS_UTILITY.get_time - l_start) || ' hsecs');
 21
 22    l_start := DBMS_UTILITY.get_time;
 23
 24    FOR i IN 1 .. l_loops LOOP
 25      SELECT dummy
 26      INTO   l_dummy
 27      FROM   dual;
 28    END LOOP;
 29
 30    DBMS_OUTPUT.put_line('Implicit: ' ||
 31                         (DBMS_UTILITY.get_time - l_start) || ' hsecs');
 32  END;
 33  /
Explicit: 332 hsecs
Implicit: 176 hsecs

PL/SQL procedure successfully completed.

Jadi, perbedaan yang signifikan terlihat jelas.

Lebih banyak contoh di sini .

1
Lalit Kumar B

Setiap pernyataan SQL yang dijalankan oleh database Oracle memiliki kursor yang terkait dengannya, yang merupakan area kerja pribadi untuk menyimpan informasi pemrosesan. Kursor implisit secara implisit dibuat oleh server Oracle untuk semua pernyataan DML dan SELECT.

Anda dapat mendeklarasikan dan menggunakan kursor eksplisit untuk memberi nama area kerja pribadi, dan mengakses informasi yang tersimpan di blok program Anda.

0
ropable

Seperti yang dinyatakan dalam jawaban lain, kursor implisit lebih mudah digunakan dan lebih rentan kesalahan. 

Dan Kursor Implisit vs. Eksplisit dalam Oracle PL/SQL menunjukkan bahwa kursor implisit hingga dua kali lebih cepat daripada yang eksplisit juga.

Sungguh aneh bahwa belum ada yang menyebutkan Implisit UNTUK LOOP Kursor :

begin
  for cur in (
    select t.id from parent_trx pt inner join trx t on pt.nested_id = t.id
    where t.started_at > sysdate - 31 and t.finished_at is null and t.extended_code is null
  )
  loop
    update trx set finished_at=sysdate, extended_code = -1 where id = cur.id;
    update parent_trx set result_code = -1 where nested_id = cur.id;
  end loop cur;
end;

Contoh lain pada SO: PL/SQL UNTUK LOOP IMPLICIT CURSOR .

Itu jauh lebih pendek daripada bentuk eksplisit.

Ini juga menyediakan solusi yang bagus untuk memperbarui beberapa tabel dari CTE .

0
Vadzim