2016-02-18 66 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