it-swarm-pt.tech

Qual é a diferença entre cursores explícitos e implícitos no Oracle?

Estou um pouco enferrujado na minha linguagem de cursor em PL/SQL. Alguém sabe disso?

25
Brian G

Um cursor implícito é aquele criado "automaticamente" para você pela Oracle quando você executa uma consulta. É mais simples de codificar, mas sofre de 

  • ineficiência (o padrão ANSI especifica que ele deve buscar duas vezes para verificar se há mais de um registro)
  • vulnerabilidade a erros de dados (se você já tiver duas linhas, isso gera uma exceção TOO_MANY_ROWS)

Exemplo

SELECT col INTO var FROM table WHERE something;

Um cursor explícito é aquele que você cria. Leva mais código, mas dá mais controle - por exemplo, você pode simplesmente abrir-buscar-fechar, se você quer apenas o primeiro registro e não se importa se há outros. 

Exemplo

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

Um cursor explícito é definido como tal em um bloco de declaração:

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

um cursor implícito é implementado diretamente em um bloco de código:

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

1.CURSOR: Quando o PLSQL emite instruções sql, ele cria uma área de trabalho privada Para analisar e executar a instrução sql chamada cursor.

2.IMPLICIT: Quando qualquer bloco PL/SQLexecutável emite uma instrução sql. PL/SQL cria cursor implícito e gerencia automaticamente significa que Implcit open & close ocorre. É usado quando a instrução sql retorna Apenas uma linha.Tem 4 atributos SQL% ROWCOUNT, SQL% FOUND, SQL% NOTFOUND, SQL% ISOPEN.

3.EXPLICIT: É criado e gerenciado pelo programador. Ele precisa de todo tempo Explícito aberto, buscar e fechar. É usado quando a instrução sql Retorna mais de uma linha. Ele também tem 4 atributos CUR_NAME% ROWCOUNT, CUR_NAME% FOUND, CUR_NAME% NOTFOUND, CUR_NAME% ISOPEN. Ele processa várias linhas usando o loop. O programador também pode passar o parâmetro para o cursor explícito.

  • Exemplo: Cursor Explícito

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

Cursores implícitos requerem memória buffer anônima. 

Cursores explícitos podem ser executados repetidamente usando seu nome. Eles são armazenados em um espaço de memória definido pelo usuário em vez de serem armazenados em uma memória buffer anônima e, portanto, podem ser facilmente acessados ​​posteriormente.

3
prince
3
pablo

Um cursor explícito é aquele que você declara, como:

CURSOR my_cursor IS
  SELECT table_name FROM USER_TABLES

Um cursor implícito é aquele criado para suportar qualquer SQL in-line que você escreve (estático ou dinâmico).

3
Dave Costa

Em resposta à primeira pergunta. Direto do Oracle documentação

Um cursor é um ponteiro para uma área privada SQL Que armazena informações sobre Processamento de uma instrução SELECT ou DML Específica.

3
Ian Carpenter

Com cursores explícitos, você tem controle total sobre como acessar informações no banco de dados. Você decide quando ABRIR o cursor, quando FETCH registros do cursor (e, portanto, da tabela ou tabelas na instrução SELECT do cursor) quantos registros para buscar e quando FECHAR o cursor. Informações sobre o estado atual do seu cursor estão disponíveis através do exame dos atributos do cursor.

Veja http://www.unix.com.ua/orelly/Oracle/prog2/ch06_03.htm para detalhes.

2
Kristian

Um cursor é uma janela SELECIONADA em uma tabela do Oracle, isso significa que um grupo de registros está presente em uma tabela do Oracle e satisfaz certas condições. Um cursor pode SELECT todo o conteúdo de uma tabela também. Com um cursor, você pode manipular colunas do Oracle, aliasando-as no resultado. Um exemplo de cursor implícito é o seguinte:

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

Com FOR ... LOOP ... END LOOP você abre e fecha o cursor automaticamente, quando todos os registros do cursor são analisados.

Um exemplo de cursor explícito é o seguinte:

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

No cursor explícito, você abre e fecha o cursor de maneira explícita, verificando a presença de registros e informando uma condição de saída.

1
UltraCommit

O Google é seu amigo: http://docstore.mik.ua/orelly/Oracle/prog2/ch06_03.htm

A PL/SQL emite um cursor implícito Sempre que você executar uma instrução SQL Diretamente em seu código, contanto que o código Não empregue um cursor explícito . Ele é chamado de cursor "implícito" Porque você, o desenvolvedor, não declara explicitamente um cursor para A instrução SQL.

Um cursor explícito é uma instrução SELECT Que é explicitamente definida Na seção de declaração do seu código E, no processo, atribuído um nome . Não existe um cursor explícito Para instruções UPDATE, DELETE, E INSERT.

1
Derek Swingley

O cursor implícito retorna apenas um registro e é chamado automaticamente. No entanto, os cursores explícitos são chamados manualmente e podem retornar mais de um registro.

1
shaiksyedbasha

Eu sei que esta é uma questão antiga, no entanto, acho que seria bom adicionar um exemplo prático para mostrar a diferença entre os dois do ponto de vista do desempenho.

Do ponto de vista do desempenho, os cursores implícitos são mais rápidos.

Vamos ver a diferença de desempenho entre os dois:

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.

Então, uma diferença significativa é claramente visível.

Mais exemplos aqui .

1
Lalit Kumar B

Cada instrução SQL executada pelo banco de dados Oracle possui um cursor associado a ela, que é uma área de trabalho privada para armazenar informações de processamento. Cursores implícitos são implicitamente criados pelo servidor Oracle para todas as instruções DML e SELECT.

Você pode declarar e usar cursores explícitos para nomear a área de trabalho privada e acessar suas informações armazenadas no bloco de programa.

0
ropable

Como afirmado em outras respostas, os cursores implícitos são mais fáceis de usar e menos propensos a erros. 

E Cursores Implícitos vs. Explícitos no Oracle PL/SQL mostra que os cursores implícitos são até duas vezes mais rápidos que os explícitos também.

É estranho que ninguém tenha ainda mencionado Implícito para o 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;

Outro exemplo em SO: PL/SQL PARA LOOP IMPLICIT CURSOR .

É muito mais curto que o formulário explícito.

Isso também fornece uma boa solução para atualização de várias tabelas do CTE .

0
Vadzim