2011-08-10 42 views
89

Tôi muốn tạo một biến mảng trong bộ nhớ có thể được sử dụng trong mã PL/SQL của tôi. Tôi không thể tìm thấy bất kỳ bộ sưu tập nào trong Oracle PL/SQL sử dụng bộ nhớ thuần túy, tất cả chúng đều có liên quan đến các bảng. Tôi đang tìm cách để làm một cái gì đó như thế này trong tôi PL/SQL (C# cú pháp):Oracle PL/SQL - Cách tạo một biến mảng đơn giản?

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

Edit: Oracle: 9i

+2

Xem: [PL/SQL Các bộ sưu tập và ghi] (http://download.oracle.com/docs/cd/B10501_01/appdev .920/a96624/05_colls.htm # 1059) – user272735

+1

Tham chiếu "bảng" có xu hướng là một sự nôn nao từ việc đặt tên bảng PL/SQL cũ. VARRAYs, Associative Arrays và các bảng lồng nhau được khai báo là tất cả các loại mảng trong bộ nhớ. – Ollie

+0

đọc liên kết này http://www.orafaq.com/wiki/VARRAY và http: //www.dba-oracle.com/tips_oracle_varray.htm – zloctb

Trả lời

178

Bạn có thể sử dụng VARRAY cho một mảng kích thước cố định:

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; 

Hoặc TABLE cho một mảng vô biên:

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

Từ "bảng" ở đây không liên quan gì đến các bảng cơ sở dữ liệu, gây nhầm lẫn. Cả hai phương thức đều tạo mảng trong bộ nhớ.

Với một trong những bạn cần cả hai khởi và mở rộng bộ sưu tập trước khi các yếu tố bổ sung:

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; 

Chỉ số đầu tiên là 1 không 0.

+37

"gây nhầm lẫn" chỉ là về tổng hợp Oracle –

+0

Tôi có chèn vào bảng giống như cách mảng không? tức là 'my_array (0): = 'một số chuỗi'; ' – Abdul

+1

@Abdul Xem câu trả lời cập nhật. –

50

Bạn chỉ có thể tuyên bố một DBMS_SQL.VARCHAR2_TABLE giữ mảng chiều dài biến bộ nhớ được lập chỉ mục bởi một 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; 

Bạn có thể sử dụng mảng kết hợp (thường được gọi là bảng PL/SQL) vì chúng là một mảng trong bộ nhớ.

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; 

Mảng kết hợp có thể chứa bất kỳ loại bản ghi nào.

Hy vọng điều đó sẽ giúp ích, Ollie.

+3

Đây là thêm vào câu trả lời của Tony ở trên đó là một câu trả lời tốt ... – Ollie

+11

Điều kiện lặp lại tăng 'VALUE_ERROR' khi bộ sưu tập trống. Tôi sẽ đề nghị sử dụng 'FOR i IN 1 .. employee_array.COUNT' trong trường hợp này – unziberla

4

Bạn cũng có thể sử dụng một 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; 

Tôi sẽ sử dụng mảng trong bộ nhớ. Nhưng với sự cải thiện .COUNT đề xuất bởi 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; 

Một giải pháp khác là sử dụng một HashMap như @Jchomel here

NB:

Với Oracle 12c bạn có thể even query arrays directly now!

6

Một giải pháp khác là sử dụng một Bộ sưu tập của Oracle như một 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; 
Các vấn đề liên quan