我尝试在工资单应用程序中为薪水计算进行一些版本管理。 我根据在任何给定时间适用的法规为每个公式版本创建了一个存储函数,然后我将这些函数的名称与每个函数的起始有效日期一起存储在表中。 然后我创建了一个函数,用于检索在给定时间适用于公式的函数的名称(并将此名称返回为varchar)。 在进行所有计算的视图中,我试图调用此函数来检索函数的名称,并使用此返回的名称来调用公式函数。所有这些都是在select指令中完成的。 我正在尝试调用其他函数返回其名称的函数,例如: (function1(param1,param2,...))(paramx,paramy,...) 但这不起作用。 有没有办法使用function1返回的名称来调用具有该名称和输入的函数(参数paramx,paramy,...)?
答案 0 :(得分:4)
函数不是可以从其他函数返回的第一类对象,并且变量中包含的函数的名称不是可以执行的实际代码。但是,您可以使用动态SQL执行您尝试执行的操作:
DECLARE
param1 NUMBER;
param2 VARCHAR2(2000);
function_name VARCHAR2(2000);
paramx NUMBER;
paramy VARCHAR2(2000);
plsql_block VARCHAR2(2000);
result NUMBER; -- assumes the function returns a NUMBER
BEGIN
param1 := 123; -- or whatever is appropriate
param2 := 'abc'; -- or whatever is appropriate
function_name := function1(param1, param2);
-- assume that function_name now contains 'some_function'
paramx := 456; -- or whatever is appropriate
paramy := 'def'; -- or whatever is appropriate
plsql_block:= 'BEGIN :r := ' || function_name || '(:px, :py); END;';
-- plsql_block should now contain 'BEGIN :r := some_function(:px, :py); END;'
EXECUTE IMMEDIATE plsql_block USING IN OUT result, paramx, paramy;
DBMS_OUTPUT.PUT_LINE('result = ' || result);
END;
祝你好运。
答案 1 :(得分:2)
如果在编译主函数时,您可能必须调用的所有函数都已知且存在,那么您可以使用您必须调用的变量来决定调用哪个函数。作为一个非常粗略的大纲:
create function master_salary(p_date date)
return number as
l_function_name all_objects.object_name%type;
begin
l_function_name := choose_function(p_date);
case l_function
when 'function_a' then
return function_a;
when 'function_b' then
return function_b(some_arg);
when 'function_c' then
return function_c(some_arg, another_arg);
else
raise_application_error(-20001, 'Unknown function ' || l_function_name);
end case;
end;
/
这避免了动态SQL,并允许您使用不同数量和/或类型的参数,并且更容易理解正在发生的事情。
如果您正在动态添加更多功能,那么您可能不应该 - 至少不在某种源控制和释放机制之外,这将允许您在步骤中维护主功能。作为后退,你可以使用默认情况尝试执行你动态的任何函数名称(如Bob Jarvis所示),如果它不是你期望的那个;但是您需要一致的参数编号和数据类型,如果可以修改从中获取函数名称的表,则可能会出现漏洞。