使用關聯陣列

關聯陣列為收集類型。

另請參閱:

如需有關收集的詳細資訊:

關於集合

集合為 PL/SQL 複合變數,可依指定順序儲存相同類型的元素,類似於一維陣列。集合的內部元件稱為元素。每個元素都具有唯一下標,可識別它在收集中的所在位置。

若要存取收集元素,請使用下標表示法:collection_name (element_subscript)。

您可以視收集元素為純量變數,您也可以將整個集合當作子程式參數傳送 (如果傳送與接收子程式都不是獨立的子程式)。

收集方法是內建的 PL/SQL 子程式,可傳回有關收集的資訊或對收集作業的資訊。若要呼叫收集方法,您可以使用點表示法:Collection_name.method_name。例如,collection_name.COUNT 會傳回集合中的元素數目。

PL/SQL具有三種收集類型:

本文件僅說明關聯陣列。

另請參閱:

關於關聯陣列

關聯陣列是一組未繫結的索引鍵 - 值組。每個索引鍵都是唯一的,可用來作為保存對應值之元素的下標。因此,不用知道元素在陣列中的位置,也不用周遊陣列就能存取元素。

關鍵碼的資料類型可以是 PLS_INTEGER 或 VARCHAR2 (長度)。

如果關鍵碼的資料類型為 PLS_INTEGER,且關聯陣列為以整數索引且為密集 (亦即元素之間沒有間距),則第一個與最後一個元素之間的每個元素都會被定義並具有值 (可以是空值)。

如果索引鍵類型為 VARCHAR2 (長度),則關聯陣列會以字串編製索引 (長度字元),而且會是稀疏;亦即,元素之間可能會有間隙。

周遊密集的關聯陣列時,您不需要小心元素之間的間隙;當您周遊稀疏的關聯陣列時,可以這樣做。

若要將值指派給關聯陣列元素,您可以使用指派運算子:

array_name(key) := value

如果索引鍵不在陣列中,則 Assignment 陳述式會將索引鍵 - 值組新增至陣列。否則,該陳述式會將 array_name (key) 的值變更為值。

在儲存暫存資料時,關聯陣列很好用。它們不會用到表格需要使用的磁碟空間或網路作業。不過,因為關聯陣列是要用於暫時儲存體,所以您無法使用 DML 敘述句來操控它們。

如果您在配套中宣告關聯陣列,並指派值給配套內文中的變數,則關聯陣列在資料庫階段作業的生命週期中會存在。否則,它的存在期間為在其中宣告它之子程式的使用期間。

另請參閱:Oracle Database PL/SQL Language Reference,瞭解有關關聯陣列的詳細資訊

宣告關聯陣列

若要宣告關聯陣列,您要宣告一個關聯陣列類型,然後宣告該類型的變數。

下列程式碼顯示最簡單的語法:

TYPE array_type IS TABLE OF element_type INDEX BY key_type;

array_name  array_type;

宣告關聯陣列的有效方法為使用游標,請使用下列程序。該程序以最簡單的形式使用每個必要敘述句,但它提供完整語法參照。

使用游標宣告關聯陣列:

  1. 在宣告的部分:

    1. 宣告游標:

       CURSOR cursor_name IS query;
      

      如需完整的宣告游標宣告語法,請參閱 Oracle Database PL/SQL Language Reference

    2. 宣告關聯陣列類型:

       TYPE array_type IS TABLE OF cursor_name%ROWTYPE
         INDEX BY { PLS_INTEGER | VARCHAR2 length }
      

      如需完整的關聯陣列類型宣告語法,請參閱 Oracle Database PL/SQL Language Reference

    3. 宣告該類型的關聯陣列變數:

       array_name  array_type;
      

      如需完整的變數宣告語法,請參閱 Oracle Database PL/SQL Language Reference

範例 5-9 使用前面的程序宣告兩個關聯陣列,employee_jobs 和 jobs_,然後宣告第三個關聯陣列 job_titles,無須使用游標。頭兩個陣列按整數編製索引;第三個陣列則按字串編製索引。

注意:宣告 employees_jobs_cursor 的 ORDER BY 子句會決定相關陣列 employee_jobs 元素的儲存體順序。

範例 5-9 宣告關聯陣列

DECLARE
  -- Declare cursor:

  CURSOR employees_jobs_cursor IS
    SELECT FIRST_NAME, LAST_NAME, JOB_ID
    FROM EMPLOYEES
    ORDER BY JOB_ID, LAST_NAME, FIRST_NAME;

  -- Declare associative array type:

  TYPE employees_jobs_type IS TABLE OF employees_jobs_cursor%ROWTYPE
    INDEX BY PLS_INTEGER;

  -- Declare associative array:

  employees_jobs  employees_jobs_type;

  -- Use same procedure to declare another associative array:

  CURSOR jobs_cursor IS
    SELECT JOB_ID, JOB_TITLE
    FROM JOBS;

  TYPE jobs_type IS TABLE OF jobs_cursor%ROWTYPE
    INDEX BY PLS_INTEGER;

  jobs_  jobs_type;

-- Declare associative array without using cursor:

  TYPE job_titles_type IS TABLE OF JOBS.JOB_TITLE%TYPE
    INDEX BY JOBS.JOB_ID%TYPE;  -- jobs.job_id%type is varchar2(10)

  job_titles  job_titles_type;

BEGIN
  NULL;
END;
/

另請參閱:

產生關聯陣列

填入密集關聯陣列的最有效方式,通常是使用具有 BULK COLLECT INTO 子句的 SELECT 敘述句。

注意:如果密集關聯陣列太大,而 SELECT 敘述句傳回的結果集太大而無法放入記憶體中,則請勿使用 SELECT 敘述句。而是使用游標和 FETCH 陳述式,將 BULK COLLECT INTO 和 LIMIT 子句填入陣列。如需有關搭配 BULK COLLECT INTO 子句使用 FETCH 敘述句的資訊,請參閱 Oracle Database PL/SQL Language Reference

您無法使用 SELECT 敘述句來填入稀疏關聯陣列 (例如「宣告關聯陣列」中的 job_titles)。相反地,您必須使用迴圈敘述句中的指派敘述句。如需迴圈陳述式的相關資訊,請參閱控制方案流程範例 5-10 使用 SELECT 敘述句來填入以整數編製索引的關聯陣列 employees_jobs 和 jobs_。然後在 FOR LOOP 陳述式中使用指派陳述式來植入關聯陣列 job_titles (以字串編製索引)。

範例 5-10 植入關聯陣列

-- Declarative part from Example 5-9 goes here.

BEGIN
  -- Populate associative arrays indexed by integer:

SELECT FIRST_NAME, LAST_NAME, JOB_ID BULK COLLECT INTO employees_jobs
  FROM EMPLOYEES ORDER BY JOB_ID, LAST_NAME, FIRST_NAME;

SELECT JOB_ID, JOB_TITLE BULK COLLECT INTO jobs_ FROM JOBS;

  -- Populate associative array indexed by string:

  FOR i IN 1..jobs_.COUNT() LOOP
    job_titles(jobs_(i).job_id) := jobs_(i).job_title;
  END LOOP;
END;
/

另請參閱:關於游標

周遊密集型關聯陣列

密集關聯陣列 (以整數為索引) 在元素之間沒有間隙 - 定義第一個與最後一個元素之間的每個元素,並具有值 (可以是空值)。

您可以使用 FOR LOOP 敘述句周遊密集陣列,如範例 5-11 中所示。

插入範例 5-10 的可執行部分中時,在植入 employees_jobs 陣列的程式碼之後,範例 5-11 中的 FOR LOOP 敘述句會依照儲存它們的順序列印 employees_jobs 陣列的元素。他們的儲存體順序是由 employee_jobs_cursor 宣告中的 ORDER BY 子句所決定,此宣告是用來宣告 employees_jobs (請參閱範例 5-9)。

FOR LOOP 敘述句的上限 employees_jobs.COUNT 會呼叫傳回陣列中元素數的收集方法。如需有關 COUNT 的詳細資訊,請參閱 Oracle Database PL/SQL Language Reference

範例 5-11 周遊密集關聯陣列

-- Code that populates employees_jobs must precede this code:

FOR i IN 1..employees_jobs.COUNT LOOP
  DBMS_OUTPUT.PUT_LINE(
    RPAD(employees_jobs(i).first_name, 23) ||
    RPAD(employees_jobs(i).last_name,  28) ||     employees_jobs(i).job_id);
  END LOOP;

結果:

William                Gietz                       AC_ACCOUNT
Shelley                Higgins                     AC_MGR
Jennifer               Whalen                      AD_ASST
Steven                 King                        AD_PRES
Lex                    De Haan                     AD_VP
Neena                  Kochhar                     AD_VP
John                   Chen                        FI_ACCOUNT
...
Jose Manuel            Urman                       FI_ACCOUNT
Nancy                  Greenberg                   FI_MGR
Susan                  Mavris                      HR_REP
David                  Austin                      IT_PROG
...
Valli                  Pataballa                   IT_PROG
Michael                Hartstein                   MK_MAN
Pat                    Fay                         MK_REP
Hermann                Baer                        PR_REP
Shelli                 Baida                       PU_CLERK
...
Sigal                  Tobias                      PU_CLERK
Den                    Raphaely                    PU_MAN
Gerald                 Cambrault                   SA_MAN
...
Eleni                  Zlotkey                     SA_MAN
Ellen                  Abel                        SA_REP
...
Clara                  Vishney                     SA_REP
Sarah                  Bell                        SH_CLERK
...
Peter                  Vargas                      ST_CLERK
Adam                   Fripp                       ST_MAN
...
Matthew                Weiss                       ST_MAN

周遊稀疏型關聯陣列

稀疏關聯陣列 (以字串建立索引) 可能在元素之間有間隙。

您可以使用 WHILE LOOP 敘述句周遊它,如範例 5-12 所示。

若要在列印 job_titles 陣列元素的範例 5-12 中執行程式碼,請完成下列步驟:

  1. 範例 5-9 的宣告部分結束時,插入此變數宣告:

     i jobs.job_id%TYPE;
    
  2. 範例 5-10 的可執行部份中,在填入 job_titles 陣列的程式碼之後,從範例 5-12 插入程式碼。

範例 5-12 周遊稀疏關聯陣列

/* Declare this variable in declarative part:

   i jobs.job_id%TYPE;

   Add this code to the executable part,
   after code that populates job_titles:
*/

i := job_titles.FIRST;

WHILE i IS NOT NULL LOOP
  DBMS_OUTPUT.PUT_LINE(RPAD(i, 12) || job_titles(i));
  i := job_titles.NEXT(i);
END LOOP;

結果:

AC_ACCOUNT  Public Accountant
AC_MGR      Accounting Manager
AD_ASST     Administration Assistant
AD_PRES     President
AD_VP       Administration Vice President
FI_ACCOUNT  Accountant
FI_MGR      Finance Manager
HR_REP      Human Resources Representative
IT_PROG     Programmer
MK_MAN      Marketing Manager
MK_REP      Marketing Representative
PR_REP      Public Relations Representative
PU_CLERK    Purchasing Clerk
PU_MAN      Purchasing Manager
SA_MAN      Sales Manager
SA_REP      Sales Representative
SH_CLERK    Shipping Clerk
ST_CLERK    Stock Clerk
ST_MAN      Stock Manager

範例 5-12 包含兩個收集方法呼叫,job_titles.FIRST 和 job_titles.NEXT (i)。job_titles.FIRST 傳回 job_titles 的第一個元素,而 job_titles.NEXT (i) 傳回成功 i 的子命令檔。有關 FIRST 的詳細資訊,請參閱 Oracle Database PL/SQL Language Reference。有關 NEXT 的詳細資訊,請參閱 Oracle Database PL/SQL Language Reference