Oracle PL/SQL 参数值来自字符串中的参数名称

Posted

技术标签:

【中文标题】Oracle PL/SQL 参数值来自字符串中的参数名称【英文标题】:Oracle PL/SQL Parameter value from parameter name in String 【发布时间】:2015-08-11 19:38:30 【问题描述】:

您好,我需要检索参数名称在不同参数中的参数值。

假设proc如下

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 参数的值,我该如何使用它?

【问题讨论】:

您要解决的业务问题是什么?显然,您可以有一个IF 块来查看p_paramname 的不同值,并根据值执行不同的代码位。然而,我猜这不是你要问的...... 嗨,贾斯汀,我正在尝试制作一个包装程序,它可以调用具有不同数量参数的不同类型的函数。我想他们的方式是获取要传入的参数顺序(p_name,p_class)让我们说p_paramname,并进一步使用函数调用中的值。 您的包装程序将调用的各种程序之间的关系是什么?如果您尝试构建一些非常动态的东西,那么您可能会错误地解决问题。但是,如果包装过程将调用的过程本质上都非常相似,那么它们的签名也应该相似。 被调用的各种程序的签名不同,为了向后兼容,我现在无法更改它。被调用的各种函数是独立的,我想使用这个包装器来动态调用它们中的任何一个,这样我就可以将它与其他应用程序一起使用。 您要支持多少个可能的参数集?您可以使用动态 PL/SQL,但这通常会产生相当复杂的代码,很难支持、维护和调试。 【参考方案1】:

如果您负担得起 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;

注意:代码语法可能并不完美,但伪代码仍然可以满足您的要求。

【讨论】:

感谢 Brainhash,如果您查看我上面的评论,了解我想要完成的工作,这个解决方案可能会变得非常庞大且难以实施。 @user3842265 以上到底有多难?您能否提供更多具有预期输出的示例/示例代码。 编辑了我的答案。请查阅。您可能需要进行一些小调整,但希望对您有所帮助 谢谢,这帮助我计划如何处理这个问题。【参考方案2】:

只需根据可能的参数名称检查 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

【讨论】:

以上是关于Oracle PL/SQL 参数值来自字符串中的参数名称的主要内容,如果未能解决你的问题,请参考以下文章

Oracle PL/SQL 将游标(来自函数)中的每个值一一分配给另一个游标

来自 Oracle pl/sql 的电子邮件中的特殊字符

Oracle PL/SQL 中的存储过程

带输入参数的 Oracle PL/SQL 函数

Oracle PL/SQL 函数 - 调用者声明参数值 => 函数返回方程解

Oracle常用函数