Domanda

Sono un po' arrugginito con il gergo del cursore in PL/SQL.Qualcuno lo sa?

È stato utile?

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).

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.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top