2016-02-18 111 views
1

我有一个plsql过程,它需要一个数据数组并更新一堆记录,我可以使用for循环执行此操作。我真的可以使用一些帮助,找出没有循环做到这一点。使用“IN”而不是“FOR”循环与集合

包装规格和身体:

create or replace PACKAGE ARRAY_EXAMPLE AS 
    type arrtype is table of test_table.name%TYPE index by pls_integer; 

    PROCEDURE PROCESS_ARRAY(stringArrayIn IN arrtype 
         , p_city   varchar2 
         , p_phone   number); 
END; 
/

create or replace PACKAGE BODY ARRAY_EXAMPLE AS 

    PROCEDURE PROCESS_ARRAY(stringArrayIn IN arrtype 
         , p_city   varchar2 
         , p_phone   number) IS 
    BEGIN 
    FOR i IN 1..stringArrayIn.Count 
    LOOP 
     update test_table t 
     set t.city = p_city 
     where t.name = stringArrayIn(i) 
     and t.phone = p_phone; 
    END LOOP; 
    END; 
END; 
/

我想拥有什么:

create or replace PACKAGE BODY ARRAY_EXAMPLE AS 

    PROCEDURE PROCESS_ARRAY(stringArrayIn IN arrtype 
          , p_city   varchar2 
          , p_phone   number) IS 
    BEGIN 
    update test_table t 
     set t.city = p_city 
     where t.phone = p_phone 
     and t.name in (stringArrayIn); 
    END; 
END; 

我得到的错误,当我尝试上述情况,请大家帮忙。非常感谢你提前。

回答

2

您需要在SQL而不是PL来定义集合/ SQL:

create type arrtype is table of VARCHAR2(100); 

create or replace PACKAGE BODY ARRAY_EXAMPLE AS 
    PROCEDURE PROCESS_ARRAY(
    stringArrayIn IN arrtype 
    , p_city  IN varchar2 
    , p_phone  IN number 
) 
    IS 
    BEGIN 
    update test_table t 
    set t.city = p_city 
    where t.phone = p_phone 
    and t.name MEMBER OF stringArrayIn 
    END; 
END; 
/

更新

初始化的实例化一个数组:后来

DECLARE 
    t_names ARRTYPE := t_names('Alice', 'Bob', 'Charlie'); 
BEGIN 
    ARRAY_EXAMPLE.PROCESS_ARRAY(
    t_names, 
    'New York City', 
    '555-2368' 
); 
END; 
/

填充数组:

DECLARE 
    t_names ARRTYPE; 
BEGIN 
    t_names := ARRTYPE(); 
    t_names.EXTEND(3); 
    t_names(1) := 'Alice'; 
    t_names(2) := 'Bob'; 
    t_names(3) := 'Charlie'; 

    ARRAY_EXAMPLE.PROCESS_ARRAY(
    t_names, 
    'New York City', 
    '555-2368' 
); 
END; 
/

你可以从第二个例子看到数组元素仍然被索引。

+0

感谢您的回复,但我无法获得索引,如果我在包体外声明,是否有解决方法? – Radan

+0

您似乎将关联数组用作普通数组(即从1到n而非稀疏数组索引)。你为什么需要这个索引? – MT0

+0

我决定采用这种方法,使用这个http://www.oracle.com/technetwork/articles/fuecks-sps-095636.html – Radan

1

如果在数据库级别创建您的类型arrtype你可以使用:

t.name in (select column_value from table(stringArrayIn)) 
+0

感谢您的回复,但如果我在数据库级别创建它,那么由于某种原因,我不能使用我所用的php应用程序所需的“由pls_integer索引”。 – Radan

1

如果您可以定义在SQL级别类型,你可以做这样的事情:

create type SQL_arrtype is table of varchar2(50) /* for example, it is the type of your name field */ 

CREATE OR REPLACE PACKAGE ARRAY_EXAMPLE AS 

    PROCEDURE PROCESS_ARRAY(
          stringArrayIn IN SQL_arrtype, 
          p_city    VARCHAR2, 
          p_phone    NUMBER 
          ); 
END; 
CREATE OR REPLACE PACKAGE BODY ARRAY_EXAMPLE AS 
    PROCEDURE PROCESS_ARRAY(
          stringArrayIn IN SQL_arrtype, 
          p_city    VARCHAR2, 
          p_phone    NUMBER 
          ) IS 
    BEGIN 
     forall i in 1 .. stringArrayIn.COUNT 
     UPDATE test_table t 
       SET t.city = p_city 
      WHERE  t.name = stringArrayIn(i) 
        AND t.phone = p_phone; 
    END; 
END; 

FORALL将比循环中的单个更新更有效。

+0

好点,我可以保持这个作为我的最后手段。如果我不能与IN一起工作。谢谢。 – Radan