1

我有一个 plsql 过程,它需要一个数据数组并更新一堆记录,我可以用一个 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;

当我尝试上述方法时出现错误,请帮助。非常感谢你。

4

3 回答 3

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;
/

您可以从第二个示例中看到数组元素仍然被索引。

于 2016-02-18T10:39:52.703 回答
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将比循环中的单个更新更有效。

于 2016-02-18T10:34:16.100 回答
1

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

t.name in (select column_value from table(stringArrayIn))
于 2016-02-18T10:26:44.553 回答