Подтвердить что ты не робот

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

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

4b9b3361

Ответ 1

Неявный курсор - это тот, который создается автоматически для вас 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;

Ответ 2

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

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

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

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

Ответ 3

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

CURSOR my_cursor IS
  SELECT table_name FROM USER_TABLES

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

Ответ 4

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

2.IMPLICIT: когда какой-либо блок PL/SQL-исполняемый код выдает команду sql.  PL/SQL создает неявный курсор и автоматически управляет  impcit открыт и закрыт. Он используется, когда возвращается заявка sql  только одна строка. У него есть 4 атрибута SQL% ROWCOUNT, SQL% FOUND,  SQL% NOTFOUND, SQL% ISOPEN.

3.EXPLICIT: он создается и управляется программистом. Он нуждается в каждом  время открыто открыто, извлекается и закрывается. Он используется, когда оператор sql  возвращает более одной строки. Он также имеет 4 атрибута  CUR_NAME% ROWCOUNT, CUR_NAME% НАЙДЕНО, 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;

Ответ 5

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

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

Ответ 6

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

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

Ответ 7

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

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

Ответ 9

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

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

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

Ответ 10

Курсор - это окно 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;
/

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

Ответ 11

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

Ответ 12

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

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

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

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.

Таким образом, заметная разница четко видна.

Дополнительные примеры здесь.

Ответ 13

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

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

Ответ 14

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

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

Странно, что никто еще не упомянул Неявный 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;

Еще один пример SO: PL/SQL FOR LOOP IMPLICIT CURSOR.

Это намного короче, чем явный вид.

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

Ответ 15

Явное...

курсор foo - это выбор * из бла; начать  открыть выход fetch при закрытии курсора yada yada yada

не использовать их, использовать неявные

курсор foo - это выбор * из blah;

для n в петле foo  x = n.some_column конец цикла

Я думаю, вы даже можете это сделать

для n in (select * from blah) loop...

Придерживайтесь неявного, они закрываются, они более читабельны, они облегчают жизнь.