2010-10-01 4 views
1

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

Через переднюю часть, я передаю имя процедуры в 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 

ответ

3

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

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 

КОРПУС заявление, которое я использовал в ОСНОВНОМ хранимую процедуру является PLSQL саз, а не ANSI SQL СЛУЧАЯ. Вы можете сказать, что для завершения инструкции CASE для версии PLSQL требуется END CASE.

+1

gah, избили меня на 1 секунду :) –

+1

@Jeffery Kemp: Theft! КРАЖА !!:) –

+0

Я всегда опаздываю ( –

4

Да.

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; 
0

Как и решение случае, можно сделать это, используя динамический 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; 

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

Ключевой вопрос: целесообразно ли .

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

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

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

1

Если вы не хотите использовать динамический 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'; 
    ... 

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

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

Смежные вопросы