Создать запись из refcursor - PullRequest
       8

Создать запись из refcursor

2 голосов
/ 19 апреля 2020

Я хотел бы создать запись из refcursor. Мой код:

set serveroutput on    
DECLARE
  c_curs    SYS_REFCURSOR;
  v_id      NUMBER;
BEGIN

  pck_prov.get_value_type_list (1, c_curs); --> procedure called here
  -- I guess this is the place where record can be created from cursor.

  LOOP 
    FETCH c_curs
    INTO  v_id;--instead of fetching into variable I would like to fetch into row
    EXIT WHEN c_curs%NOTFOUND;
    DBMS_OUTPUT.PUT_LINE(v_id);--if fetching is done into row, only selected columns can be printed, like myrow.id
  END LOOP;
  CLOSE c_curs;
END;

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

РЕДАКТИРОВАТЬ:

Код от здесь только то, что мне нужно, но выдает ошибку:

set serveroutput on
VAR c_curs refcursor;

EXECUTE pck_prov.get_value_type_list(1, :c_curs);


BEGIN
    FOR record_test IN :c_curs LOOP
        dbms_output.put_line(record_test.id);
    END LOOP;
END;

Ошибка: ошибка PLS-00456: элемент 'SQLDEVBIND1Z_1' не является курсором.

Просто чтобы уточнить вопрос:

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

Ответы [ 2 ]

1 голос
/ 01 мая 2020

Просто определите тип PL / SQL RECORD, который соответствует курсору и FETCH в нем.

DECLARE
  c_curs    SYS_REFCURSOR;
  TYPE rec_t IS RECORD ( object_name VARCHAR2(30), object_type VARCHAR2(30) );
  v_rec     rec_t;
BEGIN

  OPEN c_curs FOR 
       SELECT object_name, 
              object_type 
       FROM   dba_objects 
       WHERE  object_name like 'DBA%TAB%';  

  LOOP 
    FETCH c_curs
    INTO  v_rec;
    EXIT WHEN c_curs%NOTFOUND;
    DBMS_OUTPUT.PUT_LINE(v_rec.object_name || ' - ' || v_rec.object_type);
  END LOOP;
  CLOSE c_curs;
END;
DBA_ADVISOR_SQLA_TABLES - VIEW
DBA_ADVISOR_SQLA_TABVOL - VIEW
DBA_ADVISOR_SQLW_TABLES - VIEW
DBA_ADVISOR_SQLW_TABVOL - VIEW
DBA_ALL_TABLES - VIEW
etc...
1 голос
/ 19 апреля 2020

Начиная с Oracle 12.1, вы можете использовать процедуру DBMS_SQL.return_result. SQL Plus автоматически отображает содержимое результатов неявного оператора . Таким образом, вместо определения явных параметров курсора ref процедура RETURN_RESULT в пакете DBMS_ SQL позволяет вам передавать их неявно.

DECLARE
  c_curs    SYS_REFCURSOR;
  v_id      NUMBER;
BEGIN

  pck_prov.get_value_type_list (1, c_curs);

  DBMS_SQL.return_result(c_curs); --> Passes ref cursor output implicitly
END;
/

Фактически, нет необходимости в этом отдельном PL / Блок SQL, вы можете добавить оператор DBMS_SQL.return_result(c_curs) в свою оригинальную pck_prov.get_value_type_list саму процедуру.

...