2011-08-10 88 views
89

我想創建一個可以在我的PL/SQL代碼中使用的內存數組變量。我在Oracle PL/SQL中找不到任何使用純內存的集合,它們似乎都與表關聯。我希望做這樣的事情在我的PL/SQL(C#語法):Oracle PL/SQL - 如何創建一個簡單的數組變量?

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

編輯: 甲骨文:9I

+2

參見:[PL/SQL類別和記錄](http://download.oracle.com/docs/cd/B10501_01/appdev .920/a96624/05_colls.htm#1059) – user272735

+1

「表」引用往往是舊PL/SQL表命名的宿醉。 VARRAYs,Associative Arrays和Declared嵌套表都是內存數組類型。 – Ollie

+0

請閱讀此鏈接http://www.orafaq.com/wiki/VARRAY和http://www.dba-oracle。com/tips_oracle_varray.htm – zloctb

回答

178

可以使用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

+37

「混淆」幾乎總結了Oracle –

+0

我是否像數組一樣插入到表中?即'my_array(0):='some string';' – Abdul

+1

@Abdul查看更新後的答案。 –

50

你可以只聲明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; 

關聯數組可以容納任何組成的記錄類型。

希望它有幫助, Ollie。

+3

這是除了託尼的回答上面這是一個很好的答案... – Ollie

+11

當收集是空的迭代條件引發'VALUE_ERROR'。在這種情況下,我建議寧願使用'FOR I IN 1 .. employee_array.COUNT' – unziberla

4

您也可以使用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; 

我會使用內存陣列。但隨着.COUNT改善由uziberia建議:

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; 

另一種解決方案是使用一個HashMap像@Jchomel here

NB:

有了Oracle 12c中,你可以even query arrays directly now

6

另一個解決方案是使用Oracle集合作爲一個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; 
相關問題