【问题标题】:How to pass array as input parameter in Oracle Function如何在 Oracle 函数中将数组作为输入参数传递
【发布时间】:2017-12-14 16:54:00
【问题描述】:

我有一个使用 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 ;

请建议如何调用该函数。

【问题讨论】:

    标签: oracle collections oracle11g user-defined-types


    【解决方案1】:

    我收到错误,因为输入的数量或类型错误

    您收到错误是因为 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 在不同的模式和类型中。”

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

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

    【讨论】:

    • 嗨.. 感谢您的回复。函数 fn_insert_using_array 位于不同的模式和类型中。那么我可以在这里使用其他模式中的类型吗?我实际上将函数调用为: V_COUNT:= other_user.fn_insert_using_array(L_TAB, L_COL_NAME,l_array_orig);所以我创建了 2 种相同结构的类型,每个模式中都有一个。
    【解决方案2】:

    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

    【讨论】:

    • 嗨.. 感谢您的回复。函数 fn_insert_using_array 位于不同的模式和类型中。那么我可以在这里使用其他模式中的类型吗?我实际上将函数调用为: V_COUNT:= other_user.fn_insert_using_array(L_TAB, L_COL_NAME,l_array_orig);所以我创建了 2 种相同结构的类型,每个模式中都有一个。
    猜你喜欢
    • 2021-07-16
    • 2011-02-22
    • 2021-12-24
    • 2015-08-10
    • 1970-01-01
    • 1970-01-01
    • 2021-02-23
    • 2021-12-24
    • 2020-12-23
    相关资源
    最近更新 更多