Oracle PL/SQL String 中参数名称中的参数值
Oracle PL/SQL Parameter value from parameter name in String
您好,我需要检索参数名称在不同参数中的参数值。
假设过程如下
PROCEDURE findValue
(
p_date IN VARCHAR2,
p_name IN VARCHAR2,
p_class IN VARCHAR2,
p_paramname IN VARCHAR2,
)
IS
现在假设我想将 p_paramname
作为 p_date
传递,并在 PL/SQL 块中进一步使用 p_date
参数的值,我该如何使用它?
如果您负担得起 PL/SQL table 输入,请尝试以下逻辑:
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;
注意:代码语法可能不完美,但伪代码应该仍能满足您的要求。
只需根据可能的参数名称检查 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
您好,我需要检索参数名称在不同参数中的参数值。
假设过程如下
PROCEDURE findValue
(
p_date IN VARCHAR2,
p_name IN VARCHAR2,
p_class IN VARCHAR2,
p_paramname IN VARCHAR2,
)
IS
现在假设我想将 p_paramname
作为 p_date
传递,并在 PL/SQL 块中进一步使用 p_date
参数的值,我该如何使用它?
如果您负担得起 PL/SQL table 输入,请尝试以下逻辑:
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;
注意:代码语法可能不完美,但伪代码应该仍能满足您的要求。
只需根据可能的参数名称检查 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