it-swarm-ru.tech

В чем разница между явными и неявными курсорами в Oracle?

Я немного заржавел на моем курсоре языка в PL/SQL. Кто-нибудь знает это?

25
Brian G

Неявный курсор - это курсор, автоматически созданный для вас Oracle при выполнении запроса. Это проще для кода, но страдает от 

  • неэффективность (стандарт ANSI указывает, что он должен извлекаться дважды, чтобы проверить, существует ли более одной записи)
  • уязвимость к ошибкам данных (если вы когда-либо получите две строки, это вызывает исключение TOO_MANY_ROWS)

Пример

SELECT col INTO var FROM table WHERE something;

Явный курсор - это тот, который вы создаете сами. Он требует больше кода, но дает больше контроля - например, вы можете просто открыть-извлечь-закрыть, если вы хотите только первую запись и не заботитесь о том, есть ли другие. 

Пример

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

Явный курсор определяется как таковой в блоке объявления:

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

неявный курсор внедряется непосредственно в блок кода:

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

1.CURSOR: Когда PLSQL выдает операторы sql, он создает личную рабочую область анализировать и выполнять SQL-оператор называется курсором.

2. ПРЕДПОЛАГАЕТСЯ: когда любой исполняемый блок PL/SQL выдает оператор sql . PL/SQL создает неявный курсор и автоматически управляет средствами происходит открытие и закрытие. Используется, когда SQL-оператор возвращает только одна строка. Имеет 4 атрибута SQL% ROWCOUNT, SQL% FOUND, SQL% NOTFOUND, SQL% ISOPEN.

3. EXPLICIT: он создается и управляется программистом. Это нужно каждому время явное открытие, выборка и закрытие. Используется при выражении sql возвращает более одной строки. Он также имеет 4 атрибута CUR_NAME% ROWCOUNT, CUR_NAME% FOUND, CUR_NAME% NOTFOUND, CUR_NAME% ISOPEN. Он обрабатывает несколько строк с помощью цикла. Программист тоже может передать параметр явному курсору.

  • Пример: явный курсор

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

Неявные курсоры требуют анонимной буферной памяти. 

Явные курсоры могут выполняться снова и снова с использованием их имени. Они хранятся в определенной пользователем области памяти, а не в анонимной буферной памяти и, следовательно, могут быть легко доступны впоследствии.

3
prince

В наши дни неявные курсоры более эффективны, чем явные курсоры.

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

3
pablo

Явный курсор - это тот, который вы объявляете, например:

CURSOR my_cursor IS
  SELECT table_name FROM USER_TABLES

Неявный курсор - это курсор, созданный для поддержки любого встроенного SQL, который вы пишете (статического или динамического).

3
Dave Costa

В ответ на первый вопрос. Прямо из Оракула документация

Курсор - это указатель на частный SQL область, в которой хранится информация о обработка определенного SELECT или DML заявление.

3
Ian Carpenter

С помощью явных курсоров вы можете полностью контролировать доступ к информации в базе данных. Вы сами решаете, когда ОТКРЫТЬ курсор, когда ВЫБРАТЬ записи из курсора (и, следовательно, из таблицы или таблиц в операторе SELECT курсора), сколько записей выбрать, и когда ЗАКРЫТЬ курсор. Информация о текущем состоянии вашего курсора доступна через проверку атрибутов курсора.

Подробности смотрите в http://www.unix.com.ua/orelly/Oracle/prog2/ch06_03.htm .

2
Kristian

Курсор - это окно SELECTed в таблице Oracle, это означает, что группа записей присутствует в таблице Oracle и удовлетворяет определенным условиям. Курсор также может ВЫБРАТЬ все содержимое таблицы. С помощью курсора вы можете манипулировать столбцами Oracle, совмещая их в результате. Пример неявного курсора следующий:

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

С FOR ... LOOP ... END LOOP вы автоматически открываете и закрываете курсор, когда все записи курсора были проанализированы.

Пример явного курсора следующий:

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

В явном курсоре вы открываете и закрываете курсор явным образом, проверяя наличие записей и указывая условие выхода.

1
UltraCommit

Google - ваш друг: http://docstore.mik.ua/orelly/Oracle/prog2/ch06_03.htm

PL/SQL выдает неявный курсор всякий раз, когда вы выполняете оператор SQL прямо в вашем коде, пока что код не использует явный курсор. Это называется "неявным" курсор, потому что вы, разработчик, делаете явно не объявлять курсор для оператор SQL.

Явный курсор - это SELECT заявление, которое явно определено в разделе объявлений вашего код и, в процессе, присваивается название. Нет такой вещи как явный курсор для UPDATE, DELETE, и вставьте заявления.

1
Derek Swingley

Неявный курсор возвращает только одну запись и вызывается автоматически. Однако явные курсоры вызываются вручную и могут возвращать более одной записи.

1
shaiksyedbasha

Я знаю, что это старый вопрос, однако я думаю, что было бы неплохо добавить практический пример, чтобы показать разницу между ними с точки зрения производительности.

С точки зрения производительности неявные курсоры работают быстрее.

Давайте посмотрим на разницу в производительности между ними:

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.

Итак, значительная разница отчетливо видна.

Больше примеров здесь .

1
Lalit Kumar B

С каждым оператором SQL, выполняемым базой данных Oracle, связан курсор, который является частной рабочей областью для хранения информации обработки. Неявные курсоры неявно создаются сервером Oracle для всех операторов DML и SELECT.

Вы можете объявлять и использовать явные курсоры для именования личной рабочей области и доступа к ее хранимой информации в программном блоке.

0
ropable

Как указано в других ответах, неявные курсоры проще в использовании и менее подвержены ошибкам. 

И неявные и явные курсоры в Oracle PL/SQL показывают, что неявные курсоры работают в два раза быстрее, чем явные.

Странно, что никто еще не упомянул Неявный Курсор LOOP :

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;

Другой пример для SO: PL/SQL FOR LOOP IMPLICIT CURSOR .

Это намного короче, чем явная форма.

Это также обеспечивает хороший обходной путь для обновления нескольких таблиц из CTE .

0
Vadzim