Как выполнить процедуру оракула с параметром out sys_refcursor?

У меня есть proc в моем теле пакета:

create or replace package body MYPACKAGE is

    procedure "GetAllRules"(p_rules     out sys_refcursor)
    is
    begin
        open p_rules for
        select * from my_rules;

    end "GetAllRules";

-- etc

И я выставляю это в моей спецификации пакета.

Как выполнить эту процедуру в новом окне SQL в PL SQL Developer (или аналогичном)?

1 ответ

Решение

Вы можете выполнить процедуру относительно легко

DECLARE 
  l_rc sys_refcursor;
BEGIN
  mypackage."GetAllRules"( l_rc );
END;

Конечно, это просто возвращает курсор к вызывающему приложению. Он ничего не делает, чтобы извлечь данные из курсора, сделать что-то с этими данными или закрыть курсор. Предполагая, что ваша цель - записать некоторые данные в dbms_output (что иногда полезно для создания прототипов, но это не то, на что должен опираться производственный код), вы можете сделать что-то вроде

DECLARE 
  l_rc sys_refcursor;
  l_rec my_rules%rowtype;
BEGIN
  mypackage."GetAllRules"( l_rc );
  LOOP
     FETCH l_rc INTO l_rec;
     EXIT WHEN l_rc%NOTFOUND;

     dbms_output.put_line( <<print data from l_rec>> );
   END LOOP;

   CLOSE l_rc;
END;

Если вы действительно делаете что-то подобное с курсором в PL/SQL, я настоятельно рекомендую возвращать строго типизированный ref-курсор, а не слабо типизированный, чтобы вы могли объявить запись с точки зрения курсора. %rowtype вместо того, чтобы заставлять вызывающую сторону точно знать, какой тип объявить, и надеяться, что запрос в процедуре не изменится. Это также требует от вас явного написания кода для отображения данных, которые раздражают.

Если вы используете SQL*Plus (или что-то, что поддерживает некоторые команды SQL * Plus), вы можете немного упростить ситуацию

VARIABLE rc REFCURSOR;
EXEC mypackage."GetAllRules"( :rc );
PRINT :rc;

Кроме того, я не фанат использования чувствительных к регистру идентификаторов. Это становится очень старым, чтобы окружать идентификаторы, такие как "GetAllRules" с двойными кавычками каждый раз, когда вы хотите позвонить. Если у вас нет действительно веских причин, я бы предложил использовать стандартные идентификаторы без учета регистра. Совершенно разумно использовать идентификаторы в вашем коде с достаточной капитализацией, разумеется, просто не имеет смысла пытаться заставить их быть чувствительными к регистру в словаре данных.

Другие вопросы по тегам