2015-08-11 3 views
0

Привет Мне нужно получить значение параметра, где имя параметра находится в другом параметре.Oracle PL/SQL Значение параметра из имени параметра в String

Позволяет сказать прок, как показано ниже

PROCEDURE findValue 
(
    p_date    IN VARCHAR2, 
    p_name    IN VARCHAR2, 
    p_class    IN VARCHAR2, 
    p_paramname    IN VARCHAR2, 
) 
IS 

Теперь позволяет сказать, что я хочу передать p_paramname как p_date и далее использовать значение параметра p_date в/SQL блок PL, как я его использовать?

+1

Что такое бизнес-проблема, которую вы пытаетесь решить? Очевидно, что у вас может быть блок 'IF', который смотрит на разные значения' p_paramname' и выполняет разные биты кода в зависимости от значения. Я предполагаю, однако, это не то, что вы просите ... –

+0

Привет, Джастин, я пытаюсь сделать процедуру обертки, которая может вызывать различные типы функций, имеющих каждое разное количество параметров. Они, как я думаю, должны получить порядок параметров ('p_name, p_class'), который будет передан, позволяет говорить' p_paramname' и далее использовать значения в вызове функции. – xydac

+1

Какова связь между различными процедурами, которые будет вызывать ваша процедура обертки? Если вы пытаетесь создать что-то очень динамичное, вы, вероятно, неправильно подходите к проблеме. Но если процедуры, которые процедура обертки будет вызывать, все очень похожи по своей природе, их подписи также должны быть похожи. –

ответ

0

Если вы можете позволить себе PL входы/SQL таблицы, то попробуйте ниже логику:

CREATE TYPE param_tbl_type IS TABLE OF VARCHAR2(255); 

CREATE OR REPLACE FUNCTION 
    (p_param_names param_tbl_type, 
    p_param_values param_tbl_type) 
RETURN VARCHAR2 
IS 
    l_dyn_func_str VARCHAR2(4000); 
    l_ret_val VARCHAR2(4000); 
    vCursor integer; 
    fdbk PLS_INTEGER; 
BEGIN 

    -- make sure you have equal number of params and currespondin values. 
    -- Index much match too. i.e. if p_param_names(0) is 'p_currency' then p_param_value(0) must be 'USD' (value of currency) 
    IF p_param_names.COUNT <> p_param_values.COUNT THEN 
     raise_application_error(-2000,'Incorrect number of arguments'); 
    END IF; 

    -- use this variable to generate anonymous block code 
    l_dyn_fun_str:='BEGIN :retval := function_tobe_called ('; 

    -- loop through each parameter and add to the parameter list 
    FOR i in 1..p_param_names.COUNT LOOP 
     IF i=0 THEN 
     l_dyn_fun_str:=l_dyn_fun_str||':'||l_param_name(i); 
     ELSE 
     l_dyn_fun_str:=l_dyn_fun_str||','||':'||l_param_name(i); 
     END IF; 
    END LOOP; 

    l_dyn_fun_str:=l_dyn_fun_str||'); END;' 

    -- open cursor and associate with function call string (l_dyn_fun_str) 
    vCursor:=DBMS_SQL.OPEN_CURSOR; 
    DBMS_SQL.PARSE(vCursor,l_dyn_fun_str); 

    -- loop through parameter values and associate them with bind variables 
    DBMS_SQL.BIND_VARIABLE(vCursor,':retval',l_ret_val); 
    FOR j in 1..p_param_values.COUNT LOOP 
     DBMS_SQL.BIND_VARIABLE(vCursor, ':'||l_param_names(j), l_param_values(j)); 
    END LOOP; 
    -- execute function 
    fdbk := DBMS_SQL.EXECUTE (vCursor); 

    -- get output of function 
    DBMS_SQL.VARIABLE_VALUE (vCursor, 'retval', l_ret_val); 
    RETURN l_ret_val; 


END; 

Примечание: Синтаксис код не может быть совершенным, но псевдо-прежнему будет работать для вашего требования.

+0

Спасибо Brainhash. Если вы посмотрите на мой комментарий выше, что я пытаюсь выполнить, это решение может стать очень большим и трудным для реализации. – xydac

+0

@ user3842265 Насколько точно это будет сложно? вы можете предоставить больше примеров/пример кода с ожидаемым выходом. –

+0

Отредактировал мой ответ. Пожалуйста ознакомтесь. Возможно, вам понадобятся некоторые мелкие хитрости, но надеюсь, что это поможет – Brainhash

0

Просто проверьте значение P_PARAMNAME на возможные имена параметров и ветвь соответственно. НАПРИМЕР,

CREATE OR REPLACE PROCEDURE matt_test1 (p_date  IN VARCHAR2, 
             p_name  IN VARCHAR2, 
             p_class  IN VARCHAR2, 
             p_paramname IN VARCHAR2) IS 
BEGIN 
    CASE p_paramname 
    WHEN 'P_NAME' THEN 
     DBMS_OUTPUT.put_line ('Did something with P_NAME. Value was ' || p_name); 
    WHEN 'P_DATE' THEN 
     DBMS_OUTPUT.put_line ('Did something with P_DATE. Value was ' || p_date); 
    WHEN 'P_CLASS' THEN 
     DBMS_OUTPUT.put_line ('Did something with P_CLASS. Value was ' || p_class); 
    ELSE 
     raise_application_error (-20001, 'Invalid parameter name: ' || p_paramname); 
    END CASE; 
END matt_test1; 


begin 
    matt_test1(SYSDATE,'Fred','English 101', 'P_DATE'); 
    matt_test1(SYSDATE,'Fred','English 101', 'P_NAME'); 
    matt_test1(SYSDATE,'Fred','English 101', 'P_CLASS'); 
end; 

Выход:

Did something with P_DATE. Value was 11-Aug-2015 
Did something with P_NAME. Value was Fred 
Did something with P_CLASS. Value was English 101 
Смежные вопросы