it-swarm-eu.dev

Jaký je rozdíl mezi explicitními a implicitními kurzory v Oracle?

Jsem trochu rezavý na mém kurzoru žargonu v PL/SQL. Ví to někdo?

25
Brian G

Implicitní kurzor je vytvořen "automaticky" pro vás Oracle při spuštění dotazu. Je jednodušší kódovat, ale trpí 

  • neefektivnost (norma ANSI stanoví, že musí dvakrát přivést ke kontrole, zda existuje více než jeden záznam)
  • zranitelnost vůči chybám dat (pokud jste někdy dostali dva řádky, vyvolá výjimku TOO_MANY_ROWS)

Příklad

SELECT col INTO var FROM table WHERE something;

Explicitní kurzor je ten, který si sami vytvoříte. Trvá více kódu, ale dává větší kontrolu - například stačí otevřít-zavřít-zavřít, pokud chcete pouze první záznam a nezajímá se, jestli existují další. 

Příklad

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

Explicitní kurzor je definován jako takový v bloku deklarace:

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

implicitní kurzor je implentován přímo v bloku kódu:

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

1.CURSOR: Když PLSQL vydá příkazy sql, vytvoří soukromou pracovní plochu Pro analýzu a spuštění příkazu sql se nazývá kurzor.

2.IMPLICIT: Když nějaký PL/SQLexecutable blok vydá příkaz sql. PL/SQL vytvoří implicitní kurzor a spravuje automaticky Implcit open & close. Používá se při příkazu sql return Pouze jeden řádek. Má 4 atributy SQL% ROWCOUNT, SQL% FOUND, SQL% NOTFOUND, SQL% ISOPEN.

3.EXPLICIT: Je vytvořen a spravován programátorem. Je třeba, aby každý Časově explicitní, otevřený a zavřený čas. Používá se, když příkaz sql Vrátí více než jeden řádek. Má také 4 atributy CUR_NAME% ROWCOUNT, CUR_NAME% FOUND, CUR_NAME% NOTFOUND, CUR_NAME% ISOPEN. Zpracovává několik řádků pomocí smyčky. Programátor může parametr předat také explicitnímu kurzoru.

  • Příklad: Explicitní kurzor

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

Implicitní kurzory vyžadují anonymní vyrovnávací paměť. 

Explicitní kurzory mohou být prováděny znovu a znovu pomocí jejich jména. Jsou uloženy v uživatelsky definovaném paměťovém prostoru, místo aby byly uloženy v anonymní vyrovnávací paměti, a proto mohou být snadno přístupné.

3
prince
3
pablo

Explicitní kurzor je ten, který deklarujete, jako:

CURSOR my_cursor IS
  SELECT table_name FROM USER_TABLES

Implicitní kurzor je vytvořen tak, aby podporoval všechny in-line SQL, které píšete (statické nebo dynamické).

3
Dave Costa

V odpovědi na první otázku. Přímo ze systému Oracle dokumentace

Kurzor je ukazatel na soukromou oblast SQL , Která ukládá informace o Zpracování specifického příkazu SELECT nebo DML .

3
Ian Carpenter

S explicitními kurzory máte úplnou kontrolu nad přístupem k informacím v databázi. Rozhodnete se, kdy se má otevřít OTEVŘÍT kurzor, kdy se FETCH zaznamenává z kurzoru (a tedy z tabulky nebo tabulek v příkazu SELECT kurzoru), kolik záznamů se má načíst a kdy se má ZAVŘÍT kurzor. Informace o aktuálním stavu kurzoru jsou k dispozici prostřednictvím vyšetření atributů kurzoru.

Podrobnosti viz http://www.unix.com.ua/orelly/Oracle/prog2/ch06_03.htm .

2
Kristian

Kurzor je okno SELECT na tabulce Oracle, to znamená skupinu záznamů přítomných v tabulce Oracle a splňující určité podmínky. Kurzor může také VYBRAT celý obsah tabulky. Pomocí kurzoru můžete manipulovat se sloupci Oracle, které je ve výsledku aliasing. Příklad implicitního kurzoru je následující:

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;
/

S FOR ... LOOP ... END LOOP otevřete a zavřete kurzor automaticky, když byly všechny záznamy o kursu analyzovány.

Příklad explicitního kurzoru je následující:

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;
/

V explicitní kurzor otevřete a zavřete kurzor explicitně, kontrola přítomnosti záznamů a uvedení podmínky ukončení.

1
UltraCommit

Google je váš přítel: http://docstore.mik.ua/orelly/Oracle/prog2/ch06_03.htm

PL/SQL vydá implicitní kurzor Vždy, když provedete příkaz SQL Přímo ve vašem kódu, pokud kód Nepoužívá explicitní kurzor . Je nazýván "implicitním" Kurzorem, protože vývojář do Není explicitně deklarovat kurzor pro příkaz .

Explicitní kurzor je příkaz SELECT , Který je v sekci deklarace vašeho kódu Explicitně definován A v tomto procesu je mu přiřazen název . Neexistuje žádná taková věc jako explicitní kurzor Pro příkazy UPDATE, DELETE, A INSERT.

1
Derek Swingley

Implicitní kurzor vrátí pouze jeden záznam a automaticky se vyvolá. Explicitní kurzory jsou však volány ručně a mohou vrátit více než jeden záznam.

1
shaiksyedbasha

Vím, že se jedná o starou otázku, ale myslím si, že by bylo dobré přidat praktický příklad, který by ukázal rozdíl mezi oběma z hlediska výkonu.

Z hlediska výkonu jsou implicitní kurzory rychlejší.

Podívejme se na rozdíl ve výkonnosti:

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.

Výrazný rozdíl je tedy jasně viditelný.

Další příklady zde .

1
Lalit Kumar B

Každý příkaz SQL provedený databází Oracle má s ním přiřazený kurzor, což je soukromá pracovní plocha pro ukládání informací o zpracování. Implicitní kurzory jsou implicitně vytvořeny serverem Oracle pro všechny příkazy DML a SELECT.

Můžete zadat a použít Explicitní kurzory k pojmenování soukromé pracovní oblasti a získat přístup k uloženým informacím v bloku programu.

0
ropable

Jak je uvedeno v jiných odpovědích, implicitní kurzory jsou jednodušší a méně náchylné k chybám. 

A Implicitní vs. Explicitní kurzory v Oracle PL/SQL ukazuje, že implicitní kurzory jsou až dvakrát rychlejší než explicitní.

Je zvláštní, že nikdo ještě nezmínil Implicit FOR LOOP Cursor :

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;

Další příklad SO: PL/SQL PRO LOOP IMPLICIT CURSOR .

Je to mnohem kratší než explicitní forma.

To také poskytuje Nice řešení pro aktualizaci více tabulek z CTE .

0
Vadzim