无法在立即执行中调用函数(存储在批量收集中)
Posted
技术标签:
【中文标题】无法在立即执行中调用函数(存储在批量收集中)【英文标题】:Unable to call functions (stored in bulk collect) in execute immediate 【发布时间】:2015-09-29 03:11:08 【问题描述】:我有一列(USING_FUNCTION) 函数名称,例如 GET_FUNCTION(#value#) 和另一列 (VALUE),其中包含要使用的值
我正在尝试使用以下方法将函数名称和值集中到批量运算符中:
Select (substr(using_function, 1, instr(using_function, '(', -1) -1))
|| '(' || value || ')'
bulk collect into V_value
from table1
where using_function != 'N';
然后使用 execute immediate 调用该函数(例如 Executing GET_WEEK_DATE(-2) 将给我 16-SEP-2015 ),然后将其插入另一个表(table2):
Execute immediate ' insert into table2 (name,value) select name, '
|| V_value ||' from table1 where using_function != ''N''';
我收到一个错误:调用“||”时参数的数量或类型错误。
*ps 我避免使用循环
【问题讨论】:
请检查USING_FUNCTION列中的函数所需要的参数是否与传给它的值一致。例如,如果函数是 mod(),并且该函数需要 2 个参数,如果 VALUE 列中包含的值小于 2,则会导致错误。 感谢您的建议 :) 但是 USING_FUNCTION 列中的函数并不一致,它只需要 1 个参数 请解释为什么要避免使用循环。从table1
以及生成的语句使用的表中发布函数调用和值的真实示例数据
您以错误的方式引用 V_value。它是一个集合,因此您必须将其称为 V_value(index) 而不是单独称为 V_value。如果您不想使用循环的原因是因为它会减慢您的程序,那么forall
是您的选择。它以“批量”的方式插入您的数据,而不是逐行插入,这使其速度更快。 :)
尝试添加另一个将执行该函数的查询,因为第一个查询只是将其按原样保存在数据库中。
【参考方案1】:
PLS-00306
是编译错误。您使用||
连接运算符的方式存在问题。错误消息包括行号,这将允许您确定哪一行是错误的,但这可能是罪魁祸首:|| V_value ||
。
这是无效的,因为V_value
是一个集合。连接需要一个标量变量。如果您定义了引用索引的循环将解决编译错误:|| V_value(idx) ||
。
【讨论】:
【参考方案2】:如果您不想使用循环,则可以使用FORALL
(不是循环),这是批量收集的完美组合。我假设您的 V_value 变量是 varchar2 的集合。也许您可以将其声明为记录集合?在您的声明部分,添加以下行:
TYPE myrecord is RECORD(name table1.name%TYPE,
value table1.VALUE%TYPE);
TYPE tableofrecords is table of myrecord index by pls_integer;
V_value tableofrecords;
然后在你的块的主体内,你可以把这些行:
Select name,(substr(using_function, 1, instr(using_function, '(', -1) -1))
|| '(' || value || ')'
bulk collect into V_value
from table1
where using_function != 'N';
forall a in 1..v_value.count
insert into table2 (name,value) values (v_value(a).name,v_value(a).value);
【讨论】:
您好,通过使用 FORALL,我似乎无法在将其插入表之前执行该函数。如果调用 GET_FUNCTION(-3),它只会在列中插入 'GET_FUNCTION(-3)' 而不是 '20'。 你是对的,如果你要使用forall,你就不能执行你的函数。如果要在将函数插入表之前执行该函数,则必须循环遍历它。这指出,如果不使用任何循环,您将无法在此处实现您想要实现的目标。如果您能指出为什么要避免使用循环,也许我们可以进一步帮助您.. 它会,但它在你的情况下是不可避免的。如果这是您的原因,dbms_parallel_execute 可能会对您有所帮助。 Here's 让你开始了解它的东西【参考方案3】:尝试添加此块。它将执行存储在 v_value 中的函数
execute immediate 'select '||v_value||' from dual ' into new_v_value
注意:new_v_value 应该是数组类型。
【讨论】:
以上是关于无法在立即执行中调用函数(存储在批量收集中)的主要内容,如果未能解决你的问题,请参考以下文章