Поиск…


Синтаксис

  • Курсор cursor_name: your_select_statement
  • Курсор cursor_name (param TYPE) Является вашим_select_statement_using_param
  • FOR x in ( your_select_statement ) LOOP ...

замечания

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

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

Если вы хотите проверить, существует ли запись, а затем делать разные вещи в зависимости от того, существует ли запись или нет, тогда имеет смысл использовать операторы MERGE в чистых запросах ORACLE SQL вместо использования курсоров. (Обратите внимание, что MERGE доступен только в версиях Oracle> = 9i).

Параметрированный курсор «FOR loop»

DECLARE
  CURSOR c_emp_to_be_raised(p_sal emp.sal%TYPE) IS 
    SELECT * FROM emp WHERE  sal < p_sal;
BEGIN
  FOR cRowEmp IN c_emp_to_be_raised(1000) LOOP
    dbms_Output.Put_Line(cRowEmp .eName ||' ' ||cRowEmp.sal||'... should be raised ;)');
  END LOOP;
END;
/

Неявный курсор «FOR loop»

BEGIN
  FOR x IN (SELECT * FROM emp WHERE sal < 100) LOOP
    dbms_Output.Put_Line(x.eName ||' '||x.sal||'... should REALLY be raised :D');
  END LOOP;
END;
/
  • Первое преимущество заключается в том, что нет утомительной декларации (подумайте об этом ужасном «КУРСОРЕ», которое у вас было в предыдущих версиях)
  • второе преимущество заключается в том, что вы сначала создаете свой запрос выбора, а затем, когда у вас есть то, что вы хотите, вы сразу можете получить доступ к полям вашего запроса ( x.<myfield> ) в вашем цикле PL / SQL
  • Цикл открывает курсор и выбирает по одной записи за каждый цикл. В конце цикла курсор закрывается.
  • Неявные курсоры быстрее, потому что работа интерпретатора возрастает по мере увеличения кода. Чем меньше кода, тем меньше работает интерпретатор.

Работа с SYS_REFCURSOR

SYS_REFCURSOR можно использовать как возвращаемый тип, когда вам нужно легко обрабатывать список, возвращенный не из таблицы, а, более конкретно, из функции:

функция, возвращающая курсор

CREATE OR REPLACE FUNCTION list_of (required_type_in IN VARCHAR2)
   RETURN SYS_REFCURSOR
IS
   v_ SYS_REFCURSOR;
BEGIN
   CASE required_type_in
      WHEN 'CATS'
      THEN
         OPEN v_ FOR
           SELECT nickname FROM (
                select 'minou' nickname from dual
      union all select 'minâ'           from dual
      union all select 'minon'          from dual         
           );
      WHEN 'DOGS'
      THEN
         OPEN v_ FOR
              SELECT dog_call FROM (
                select 'bill'   dog_call from dual
      union all select 'nestor'          from dual
      union all select 'raoul'           from dual         
           );
   END CASE;
   -- Whit this use, you must not close the cursor.
   RETURN v_;
END list_of;
/

и как его использовать:

DECLARE
   v_names   SYS_REFCURSOR;
   v_        VARCHAR2 (32767);
BEGIN
   v_names := list_of('CATS');
   LOOP
      FETCH v_names INTO v_;
      EXIT WHEN v_names%NOTFOUND;
      DBMS_OUTPUT.put_line(v_);
   END LOOP;
   -- here you close it
   CLOSE v_names;
END;
/

Обработка КУРСОРА

  • Объявить курсор для сканирования списка записей
  • Открой это
  • Получить текущую запись в переменные (это увеличивает положение)
  • Использовать %notfound для обнаружения конца списка
  • Не забудьте закрыть курсор, чтобы ограничить потребление ресурсов в текущем контексте

-

DECLARE
  CURSOR curCols IS -- select column name and type from a given table
         SELECT column_name, data_type FROM all_tab_columns where table_name='MY_TABLE';
  v_tab_column all_tab_columns.column_name%TYPE;
  v_data_type all_tab_columns.data_type%TYPE;
  v_ INTEGER := 1;
BEGIN
  OPEN curCols;
  LOOP
     FETCH curCols INTO v_tab_column, v_data_type;
     IF curCols%notfound OR v_ > 2000 THEN
       EXIT;
     END IF;
     dbms_output.put_line(v_||':Column '||v_tab_column||' is of '|| v_data_type||' Type.');
     v_:= v_ + 1;
  END LOOP;

  -- Close in any case
  IF curCols%ISOPEN THEN  
     CLOSE curCols;
  END IF;
END;
/


Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow