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

How to pass array as input parameter in Oracle Function

我有使用 FORALL 批量插入数据的功能。

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 ;

请建议如何调用函数。

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

I am getting error as wrong number or type of inputs

您收到错误是因为 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 ;

"The function fn_insert_using_array is in a different schema and also the Type."

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

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