可以执行任何过程/函数的通用过程

时间:2013-09-19 20:28:18

标签: plsql oracle11g

输入
包装名称(IN)
程序名称(或功能名称)(IN)
一个由整数索引的表,它将包含将用于执行过程(IN / OUT)的值。

E.g
我们假设我们要执行以下过程

utils.get_emp_num(emp_name IN VARCHAR
                  emp_last_name IN VARCHAR
                  emp_num OUT NUMBER
                  result  OUT VARCHAR);

我们将创建的程序将作为输入:

package_name = utils
procedure_name = get_emp_num
table = T[1] -> name
        T[2] -> lastname
        T[3] -> 0   (any value) 
        T[4] -> N   (any value)

run_procedure(package_name,
              procedure_name,
              table)

主程序应该返回与输入中设置的相同的表,但是具有程序的执行结果

table =  T[1] -> name
         T[2] -> lastname
         T[3] -> 78734 (new value)
         T[4] -> F     (new value)

有什么想法吗?

2 个答案:

答案 0 :(得分:1)

您可以使用EXECUTE IMMEDIATE实现它。基本上,您构建以下形式的SQL语句:

sql := 'BEGIN utils.get_emp_num(:1, :2, :3, :4); END;';

然后执行它:

EXECUTE IMMEDIATE sql USING t(1), t(2), OUT t(3), OUT t(4);

现在有了棘手的部分:对于每个参数和IN / OUT组合,您需要一个单独的EXECUTE IMMEDIATE语句。要弄清楚参数的数量及其方向,首先需要查询ALL_ARGUMENTS表。

您可以通过将整个表作为绑定参数传递而不是为每个表元素传递单独的绑定参数来简化它。但我还没弄清楚你会怎么做。

接下来你应该考虑的事情:你使用的表格T的元素将有一个类型:VARCHAR,NUMBER等等。所以你有数字和字符串的当前混合不会起作用。

BTW:为什么你还想要这样一个动态的呼叫机制呢?

答案 1 :(得分:0)

从all_arguments表中获取argument_name,data_type,in_out和位置

构建PLSQL块

DECLARE
    loop over argument_name and create the declare section
    argument_name data_type if in_out <> OUT then := VALUE OF THE INPUT otherwise NULL
BEGIN

--In the case of function create an additional argument 
function_var:= package_name.procedure_name( loop over argument_name);

--use a table of any_data, declare it as global in the package

if function then
    package_name.ad_table.EXTEND;
    package_name.ad_table(package_name.ad_table.LAST):= function_var;
end if

--loop over argument_name IF IN_OUT <> IN
package_name.ad_table.EXTEND;
package_name.ad_table(package_name.ad_table.LAST):= 

if data_type = VARCHAR2 then := ConvertVarchar2(argument_name)
else if NUMBER then ConvertNumber 
else if DATE then ConvertDate
...

END;

结果存储在表格中。 要获得价值,请使用Access *功能