Вызов функции с именем переменной? - PullRequest
1 голос
/ 01 октября 2010

У меня есть один пакет с разными процедурами и одна основная процедура, с помощью которой я вызываю другие процедуры.

Через интерфейс я передаю имя процедуры в main(). Есть ли способ, с помощью которого можно вызвать процедуру, просто записав имя параметра, содержащее («Имя процедуры, которую нужно вызвать»)?

CREATE OR REPLACE PACKAGE BODY UPLOAD_PKG
IS

  --This procedure will populate LOG with messages
  PROCEDURE PRINT_LOG_PR IS
  BEGIN
    fnd_file.put_line(fnd_file.LOG,'ABC');
  END PRINT_LOG_PR;

  --This procedure will populate LOG with messages
  PROCEDURE PRINT_LOG1 IS
  BEGIN
    fnd_file.put_line(fnd_file.LOG, 'XYZ');
  END PRINT_LOG1;

  PROCEDURE Main( p_obj_type VARCHAR2
                 , errbuf VARCHAR2
                 , retcode VARCHAR2) IS
  BEGIN 
    -Is this possible for eg i have passed PRINT_LOG1 here and calling PRINT_LOG1
     p_obj_type ;-
  END main;
END UPLOAD_PKG

Ответы [ 4 ]

4 голосов
/ 01 октября 2010

Да.

PROCEDURE Main( p_obj_type VARCHAR2
              , errbuf VARCHAR2
              , retcode VARCHAR2) IS
BEGIN 
  CASE p_obj_type
  WHEN 'PRINT_LOG_PR' THEN PRINT_LOG_PR;
  WHEN 'PRINT_LOG1' THEN PRINT_LOG1;
  END CASE;
END main;
3 голосов
/ 01 октября 2010

Использование:

CREATE OR REPLACE PACKAGE BODY UPLOAD_PKG
IS

  --This procedure will populate LOG with messages
  PROCEDURE PRINT_LOG_PR IS
  BEGIN
    fnd_file.put_line(fnd_file.LOG,'ABC');
  END PRINT_LOG_PR;

  --This procedure will populate LOG with messages
  PROCEDURE PRINT_LOG1 IS
  BEGIN
    fnd_file.put_line(fnd_file.LOG, 'XYZ');
  END PRINT_LOG1;

  PROCEDURE MAIN( p_obj_type VARCHAR2
                 , errbuf VARCHAR2
                 , retcode VARCHAR2) IS
  BEGIN 

    CASE p_obj_type
      WHEN 'PRINT_LOG_PR' THEN UPLOAD_PKG.PRINT_LOG_PR;
      WHEN 'PRINT_LOG1' THEN UPLOAD_PKG.PRINT_LOG1;
    END CASE;

  END MAIN;

END UPLOAD_PKG

Оператор CASE, который я использовал в хранимой процедуре MAIN, - это оператор PLSQL CASE, а не ANSI SQL CASE.Вы можете сказать, потому что версия PLSQL требует END CASE для завершения оператора CASE.

1 голос
/ 03 октября 2010

Если вы не хотите использовать динамический pl / sql, то я бы предложил использовать постоянные переменные в заголовке пакета для выбора между процедурами (максимально избегая жесткого кодирования).

Основной вызов процедуры будетнапример:

UPLOAD_PKG.MAIN(UPLOAD_PKG.C_PRINT_LOG_PR, v_errbuf, v_retcode);

И в основном теле вы должны использовать регистр следующим образом:

CASE p_obj_type
  WHEN C_PRINT_LOG_PR THEN UPLOAD_PKG.PRINT_LOG_PR;
  WHEN C_PRINT_LOG1   THEN UPLOAD_PKG.PRINT_LOG1;
  ELSE RAISE SOME_ERROR;
END CASE;

В заголовке вы можете определить постоянные переменные, которые будут содержать все:

CREATE OR REPLACE PACKAGE UPLOAD_PKG
IS
  C_PRINT_LOG_PR CONSTANT VARCHAR2(22) := 'What ever';
  C_PRINT_LOG1   CONSTANT VARCHAR2(22) := 'What ever2';
  ...

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

Но для любопытства вы можете сказать нам, почему вам нужно использовать package таким образом?

0 голосов
/ 01 октября 2010

Как и решение CASE, возможно сделать это, используя динамический PL / SQL.

PROCEDURE MAIN( p_obj_type VARCHAR2
             , errbuf VARCHAR2
             , retcode VARCHAR2) IS
 BEGIN 
    EXECUTE IMMEDIATE 'begin upload_pkg.'||p_obj_type|| '; end;';
END MAIN;

Простые параметры (Date, Varhar2, Number) могут быть переданы IN OUT с помощью команды USING.

Ключевой вопрос: желательно .

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

Также каждая динамическая команда sql или pl / sql влечет за собой небольшие накладные расходы на анализ по сравнению с фактическим скомпилированным кодом. Эти издержки невелики, но становятся заметными, если они выполняются внутри цикла.

Наконец, вызываемый код должен иметь одинаковую сигнатуру параметра.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...