Qual è la differenza tra cursori espliciti e impliciti in Oracle?
Domanda
Sono un po' arrugginito con il gergo del cursore in PL/SQL.Qualcuno lo sa?
Soluzione
Un cursore implicito è quello creato "automaticamente" per te da Oracle quando esegui una query.È più semplice da programmare, ma ne soffre
- inefficienza (lo standard ANSI specifica che deve essere recuperato due volte per verificare se è presente più di un record)
- vulnerabilità agli errori dei dati (se ottieni due righe, solleva un'eccezione TOO_MANY_ROWS)
Esempio
SELECT col INTO var FROM table WHERE something;
Un cursore esplicito è quello creato dall'utente.Richiede più codice, ma offre più controllo: ad esempio, puoi semplicemente aprire-recuperare-chiudere se desideri solo il primo record e non ti interessa se ce ne sono altri.
Esempio
DECLARE
CURSOR cur IS SELECT col FROM table WHERE something;
BEGIN
OPEN cur;
FETCH cur INTO var;
CLOSE cur;
END;
Altri suggerimenti
Un cursore esplicito è definito come tale in un blocco di dichiarazione:
DECLARE
CURSOR cur IS
SELECT columns FROM table WHERE condition;
BEGIN
...
un cursore implicito viene implementato direttamente in un blocco di codice:
...
BEGIN
SELECT columns INTO variables FROM table where condition;
END;
...
1.CURSORE:Quando PLSQL emette dichiarazioni SQL, crea un'area di lavoro privata per analizzare ed eseguire l'istruzione SQL si chiama cursore.
2. IMPLICITO:Quando qualsiasi blocco eseguibile PL/SQL emette un'istruzione SQL.PL/SQL crea un cursore implicito e gestisce automaticamente Implcit Open & Close.Ha usato quando l'istruzione SQL restituisce solo una riga. Ha 4 attributi SQL%RowCount, SQL%trovati, SQL%Notfound, SQL%Isopen.
3.ESPLICITO:È creato e gestito dal programmatore.Ha bisogno ogni volta esplicito aperto, recupera e chiuso.Viene utilizzato quando l'istruzione SQL restituisce più di una riga.Ha anche 4 attributi CUR_NAME%RowCount, CUR_NAME%Trovato, CUR_NAME%NotFound, CUR_NAME%ISOPEN.Elabora diverse righe utilizzando loop.Il programmatore può passare il parametro anche al cursore esplicito.
- Esempio:Cursore esplicito
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;
Un cursore esplicito è quello che dichiari, come:
CURSOR my_cursor IS
SELECT table_name FROM USER_TABLES
Un cursore implicito è quello creato per supportare qualsiasi SQL in linea che scrivi (statico o dinamico).
Al giorno d'oggi i cursori impliciti sono più efficienti dei cursori espliciti.
http://www.oracle.com/technology/oramag/oracle/04-sep/o54plsql.html
http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:1205168148688
In risposta alla prima domanda.Direttamente dall'Oracolo documentazione
Un cursore è un puntatore a un'area SQL privata che memorizza informazioni sull'elaborazione di una specifica istruzione selezionata o DML.
I cursori impliciti richiedono memoria buffer anonima.
I cursori espliciti possono essere eseguiti più e più volte utilizzando il loro nome. Sono archiviati nello spazio di memoria definito dall'utente anziché essere archiviati in una memoria buffer anonima e quindi sono facilmente accessibili in seguito.
Con i cursori espliciti, hai il controllo completo su come accedere alle informazioni nel database.Sei tu a decidere quando APRIRE il cursore, quando PRENDERE i record dal cursore (e quindi dalla tabella o dalle tabelle nell'istruzione SELECT del cursore), quanti record recuperare e quando CHIUDERE il cursore.Le informazioni sullo stato corrente del cursore sono disponibili esaminando gli attributi del cursore.
Vedere http://www.unix.com.ua/orelly/oracle/prog2/ch06_03.htm per dettagli.
Google è tuo amico: http://docstore.mik.ua/orelly/oracle/prog2/ch06_03.htm
PL/SQL emette un cursore implicito ogni volta che si esegue un'istruzione SQL direttamente nel codice, a condizione che tale codice non utilizzi un cursore esplicito.Si chiama cursore "implicito" perché tu, lo sviluppatore, non dichiari esplicitamente un cursore per l'istruzione SQL.
Un cursore esplicito è un'istruzione selezionata che è esplicitamente definita nella sezione Dichiarazione del codice e, nel processo, assegnato un nome.Non esiste un cursore esplicito per le dichiarazioni di aggiornamento, eliminazione e inserimento.
Un cursore è una finestra SELECTed su una tabella Oracle, ciò significa un gruppo di record presenti in una tabella Oracle e che soddisfano determinate condizioni.Un cursore può anche SELEZIONARE tutto il contenuto di una tabella.Con un cursore puoi manipolare le colonne Oracle, creando un alias nel risultato.Un esempio di cursore implicito è il seguente:
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;
/
Con PER...CICLO CONTINUO...END LOOP si apre e si chiude automaticamente il cursore, quando tutti i record del cursore sono stati analizzati.
Un esempio di cursore esplicito è il seguente:
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;
/
Nel cursore esplicito si apre e si chiude il cursore in modo esplicito, verificando la presenza di record e dichiarando una condizione di uscita.
Il cursore implicito restituisce solo un record e viene chiamato automaticamente.Tuttavia, i cursori espliciti vengono chiamati manualmente e possono restituire più di un record.
So che è una vecchia domanda, tuttavia penso che sarebbe bene aggiungere un esempio pratico per mostrare la differenza tra i due dal punto di vista prestazionale.
Dal punto di vista delle prestazioni, i cursori impliciti sono più veloci.
Vediamo la differenza prestazionale tra i due:
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.
Quindi, una differenza significativa è chiaramente visibile.
Altri esempi Qui.
In PL/SQL, un cursore è un puntatore a quest'area di contesto.Contiene tutte le informazioni necessarie per l'elaborazione della dichiarazione.
Cursori impliciti:I cursori impliciti vengono creati automaticamente da Oracle ogni volta che viene eseguita un'istruzione SQL, quando non è presente alcun cursore esplicito per l'istruzione.I programmatori non possono controllare i cursori impliciti e le informazioni in essi contenuti.
Cursori espliciti:I cursori espliciti sono cursori definiti dal programmatore per ottenere un maggiore controllo sull'area di contesto.Un cursore esplicito dovrebbe essere definito nella sezione di dichiarazione del blocco PL/SQL.Viene creato su un'istruzione SELECT che restituisce più di una riga.
La sintassi per creare un cursore esplicito è:
CURSOR cursor_name IS select_statement;
A ogni istruzione SQL eseguita dal database Oracle è associato un cursore, che è un'area di lavoro privata in cui archiviare le informazioni di elaborazione.I cursori impliciti vengono creati implicitamente dal server Oracle per tutte le istruzioni DML e SELECT.
È possibile dichiarare e utilizzare i cursori espliciti per denominare l'area di lavoro privata e accedere alle informazioni memorizzate nel blocco di programma.
Come affermato in altre risposte, i cursori impliciti sono più facili da usare e meno soggetti a errori.
E Implicito vs.Cursori espliciti in Oracle PL/SQL mostra che anche i cursori impliciti sono fino a due volte più veloci di quelli espliciti.
È strano che nessuno ne avesse ancora parlato Cursore FOR LOOP implicito:
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;
Un altro esempio su SO: PL/SQL PER CURSORE IMPLICITO DI LOOP.
È molto più breve della forma esplicita.
Ciò fornisce anche una soluzione alternativa per aggiornamento di più tabelle da CTE.
Esplicito...
il cursore foo è selezionato * da blah;Inizia Open Fetch Exit quando si chiude il cursore yada yada yada
non usarli, usa implicito
il cursore foo è selezionato * da blah;
per n in foo loop x = n.some_column end loop
Penso che tu possa fare anche questo
for n in (seleziona * da blah) ciclo...
Attenersi all'implicito, si chiudono, sono più leggibili, semplificano la vita.