首页 文章

Oracle PL / SQL - 如何创建一个简单的数组变量?

提问于
浏览
106

我想创建一个可以在我的PL / SQL代码中使用的内存数组变量 . 我在Oracle PL / SQL中找不到任何使用纯内存的集合,它们似乎都与表相关联 . 我想在我的PL / SQL(C#语法)中做类似的事情:

string[] arrayvalues = new string[3] {"Matt", "Joanne", "Robert"};

Edit: Oracle:9i

4 回答

  • 8

    另一种解决方案是将Oracle Collection用作Hashmap:

    declare 
    -- create a type for your "Array" - it can be of any kind, record might be useful
      type hash_map is table of varchar2(1000) index by varchar2(30);
      my_hmap hash_map ;
    -- i will be your iterator: it must be of the index's type
      i varchar2(30);
    begin
      my_hmap('a') := 'apple';
      my_hmap('b') := 'box';
      my_hmap('c') := 'crow';
    -- then how you use it:
    
      dbms_output.put_line (my_hmap('c')) ;
    
    -- or to loop on every element - it's a "collection"
      i := my_hmap.FIRST;
    
      while (i is not null)  loop     
        dbms_output.put_line(my_hmap(i));      
        i := my_hmap.NEXT(i);
      end loop;
    
    end;
    
  • 207

    您可以将VARRAY用于固定大小的数组:

    declare
       type array_t is varray(3) of varchar2(10);
       array array_t := array_t('Matt', 'Joanne', 'Robert');
    begin
       for i in 1..array.count loop
           dbms_output.put_line(array(i));
       end loop;
    end;
    

    或者表为无界数组:

    ...
       type array_t is table of varchar2(10);
    ...
    

    这里的“表”一词与数据库表无关,令人困惑 . 这两种方法都创建了内存数组 .

    使用其中任何一个,您需要在添加元素之前初始化和扩展集合:

    declare
       type array_t is varray(3) of varchar2(10);
       array array_t := array_t(); -- Initialise it
    begin
       for i in 1..3 loop
          array.extend(); -- Extend it
          array(i) := 'x';
       end loop;
    end;
    

    第一个索引是1而不是0 .

  • 11

    您可以声明DBMS_SQL.VARCHAR2_TABLE来保存由BINARY_INTEGER索引的内存中可变长度数组:

    DECLARE
       name_array dbms_sql.varchar2_table;
    BEGIN
       name_array(1) := 'Tim';
       name_array(2) := 'Daisy';
       name_array(3) := 'Mike';
       name_array(4) := 'Marsha';
       --
       FOR i IN name_array.FIRST .. name_array.LAST
       LOOP
          -- Do something
       END LOOP;
    END;
    

    您可以使用关联数组(以前称为PL / SQL表),因为它们是内存数组 .

    DECLARE
       TYPE employee_arraytype IS TABLE OF employee%ROWTYPE
            INDEX BY PLS_INTEGER;
       employee_array employee_arraytype;
    BEGIN
       SELECT *
         BULK COLLECT INTO employee_array
         FROM employee
        WHERE department = 10;
       --
       FOR i IN employee_array.FIRST .. employee_array.LAST
       LOOP
          -- Do something
       END LOOP;
    END;
    

    关联数组可以保存任何记录类型 .

    希望它有所帮助,奥利 .

  • 56

    你也可以使用 oracle defined collection

    DECLARE 
      arrayvalues sys.odcivarchar2list;
    BEGIN
      arrayvalues := sys.odcivarchar2list('Matt','Joanne','Robert');
      FOR x IN ( SELECT m.column_value m_value
                   FROM table(arrayvalues) m )
      LOOP
        dbms_output.put_line (x.m_value||' is a good pal');
      END LOOP;
    END;
    

    我会使用内存中的数组 . 但随着uziberia提出的_1528175改善:

    DECLARE
      TYPE t_people IS TABLE OF varchar2(10) INDEX BY PLS_INTEGER;
      arrayvalues t_people;
    BEGIN
      SELECT *
       BULK COLLECT INTO arrayvalues
       FROM (select 'Matt' m_value from dual union all
             select 'Joanne'       from dual union all
             select 'Robert'       from dual
        )
      ;
      --
      FOR i IN 1 .. arrayvalues.COUNT
      LOOP
        dbms_output.put_line(arrayvalues(i)||' is my friend');
      END LOOP;
    END;
    

    另一种解决方案是使用像@Jchomel那样的Hashmap here .

    NB:

    使用Oracle 12c,您可以even query arrays directly now

相关问题