如何在Oracle Function中传递数组作为输入参数

时间:2017-12-14 07:50:11

标签: oracle collections oracle11g user-defined-types

我有一个使用FORALL BULK插入数据的函数。

create or replace type l_array_tab as table of number;

create or replace FUNCTION fn_insert_using_array(
    L_TAB         VARCHAR2,
    L_COL_NAME    VARCHAR2,
    L_ARRAY L_ARRAY_TAB)
    RETURN NUMBER
AS
    SQL_STMT  VARCHAR2(32767);
    sql_count NUMBER;
BEGIN
    FORALL i IN L_ARRAY.first .. L_ARRAY.LAST

        EXECUTE immediate 'INSERT  INTO my_table 
               Select * from '||L_TAB
               ||' where '||L_COL_NAME||' := :1' using L_ARRAY(i);
        sql_count:= SQL%ROWCOUNT;

  RETURN SQL_COUNT;
end;

我需要在此示例中从另一个存储过程或plsql块调用此函数。在调用此函数时,我收到的错误是错误的数字或输入类型。

这就是我调用函数的方式:

create or replace type l_array_orig_tab as table of number;

Declare
    l_array_orig l_array_orig_tab :=l_array_orig_tab();
    l_tab varchar2(30): ='my_tab_orig';
    l_col_name varchar2(30) :='insert_id';
    V_COUNT NUMBER;
    cursor c1 is select * from my_tab_orig;
begin
    open c1;
    LOOP
        FETCH c1 BULK COLLECT INTO l_array_orig limit 1000;
        EXIT WHEN L_ARRAY_orig.COUNT =0;
        V_COUNT:= fn_insert_using_array(L_TAB, L_COL_NAME,l_array_orig); 
    END LOOP;
END ;

请建议如何调用此功能。

2 个答案:

答案 0 :(得分:0)

l_array_orig_tab!= l_array_tab 你必须使用相同的类型或在类型之间进行强制转换。

Declare
l_array_orig l_array_orig_tab;
new_array    l_array_tab;
l_tab varchar2(30): ='my_tab_orig';
l_col_name varchar2(30) :='insert_id';
V_COUNT NUMBER;
cursor c1 is select * from my_tab_orig;
begin
open c1;
LOOP
FETCH c1 BULK COLLECT INTO l_array_orig limit 1000;
select cast( l_array_orig as l_array_tab) into new_array from dual;
EXIT WHEN L_ARRAY_orig.COUNT =0;
V_COUNT:= fn_insert_using_array(L_TAB, L_COL_NAME,new_array); 
END LOOP;
END ;

演员如何运作。
select cast( variable as destination_type) into var_destination_type from dual

答案 1 :(得分:0)

  

我收到错误的数字或输入类型

您收到错误是因为l_array_orig_tabl_array_tab的类型不同。它们具有相同的结构并不重要,只要Oracle知道它们是不同的类型。 Oracle是一个数据库引擎,它强烈地强制实现类型安全。这里有no duck typing

所以最简单的解决方案是在调用函数时使用正确的类型:

Declare
    l_array_orig l_array_tab :=l_array_tab(); -- change this declaration
    l_tab varchar2(30): ='my_tab_orig';
    l_col_name varchar2(30) :='insert_id';
    V_COUNT NUMBER;
    cursor c1 is select * from my_tab_orig;
begin
    open c1;
    LOOP
        FETCH c1 BULK COLLECT INTO l_array_orig limit 1000;
        EXIT WHEN L_ARRAY_orig.COUNT =0;
        V_COUNT:= fn_insert_using_array(L_TAB, L_COL_NAME,l_array_orig); 
    END LOOP;
END ;
  

"函数fn_insert_using_array在不同的模式中,也在Type中。"

因此拥有该函数的模式已授予您对该函数的EXECUTE特权。但是他们还需要在类型上授予EXECUTE。这是他们的责任:他们在签名中使用UDT定义了该函数,因此他们必须为您提供调用它所需的所有权限。

我不知道这是否只是在SO上发布的玩具示例,但如果不是,则不需要创建这样的类型。而是使用记录的Oracle内置数字表sys.odcinumberlist