---
title: "关联数组 - OceanBase 数据库 V4.5.0 | OceanBase 文档中心"
description: 关联数组 关联数组是一组键值对的集合。每个键都是唯一的，用于保存相应数据的元素的下标。 功能适用性 该内容仅适用于 OceanBase 数据库企业版。OceanBase 数据库社区版暂不支持。 可以使用 variable_name(index) 语法，通过其唯一索引访问集合变量的每个元素，而无需知道它们所在的数组位置…
---
切换语言

- 中文站 - 简体中文
- International - English
- 日本站 - 日本語

文档反馈![](https://mdn.alipayobjects.com/huamei_22khvb/afts/img/A*P8CuR4UJ_FkAAAAAAAAAAAAADiGDAQ/original) OceanBase 数据库分布式版 - V 4.5.0

# 关联数组

更新时间：2026-03-26 17:56:44

[编辑](https://github.com/oceanbase/oceanbase-doc/edit/V4.5.0/zh-CN/700.reference/600.pl-reference/300.pl-oracle/400.collections-and-records-oracle/300.associative-array-oracle.md)  

关联数组是一组键值对的集合。每个键都是唯一的，用于保存相应数据的元素的下标。

#### 功能适用性

该内容仅适用于 OceanBase 数据库企业版。OceanBase 数据库社区版暂不支持。

可以使用 `variable_name(index)` 语法，通过其唯一索引访问集合变量的每个元素，而无需知道它们所在的数组位置，也不用遍历整个数组。

键的数据类型可以是 `PLS_INTEGER` 或 `VARCHAR2`。说明如下：

- 如果键的数据类型是 `PLS_INTEGER`，关联数组是按整数索引（Indexed by Integer）并且是密集型（指元素之间没有空隙），则从第一个元素到最后一个元素之间的每个元素都是有定义的，并且有值（值可以是 `NULL` ）。
 - 如果键的数据类型是 `VARCHAR2`，关联数组是按字符串索引（Indexed by String）并且是稀疏型（指元素之间可能有空隙）。

  #### 说明

  当遍历密集的关联数组时，不需要考虑元素之间的空隙；当遍历稀疏的关联数组时，需要留意空隙。

## 关联数组元素赋值

可以使用如下赋值表达式为一个关联数组元素赋值：

```javascript
array_name(key) := value

```

如果键不在数组中，赋值语句就会向数组中添加一个键值对；否则，赋值语句就会更新该键对应的值为新的值。

特别的，关联数组可以用于临时存储数据，它们不需要像表一样占用空间或网络资源，但是因为关联数组只是为了临时存储，所以不可以进行 DML 语句操作。

如果在包里面定义关联数组变量，并在包体里赋值，则关联数组在数据库会话期间都保持可见；否则，只在所在的子程序范围内可见。

## 声明关联数组

要声明关联数组，需要先声明一个关联数组类型，然后声明这个类型的变量。最简单的语法格式如下：

```javascript
TYPE array_type IS TABLE OF element_type INDEX BY key_type;
array_name array_type;

```

**示例：声明关联数组**

```javascript
obclient> DECLARE
    TYPE TYPE_SALARY IS TABLE OF NUMBER   -- 关联数组的类型
          INDEX BY VARCHAR2(64);           -- 索引的类型是字符串
    salary TYPE_SALARY;             -- 关联数组变量
    n  VARCHAR2(64);                     -- 标量变量
BEGIN
    -- 向关联数组中添加键值对
    salary('Tom')  := 2000;
    salary('Mike') := 7500;
    salary('Steve') := 10000;
    -- 打印关联数组
    n :=salary.FIRST;    -- 获得关联数组的第一个元素
    WHILE n IS NOT NULL
    LOOP
        DBMS_OUTPUT.PUT_LINE('Salary of ' || n || ' is ' || salary(n));
        n := salary.Next(n);    -- 获得关联数组的下一个元素
    END LOOP;
END;
/
Query OK, 0 rows affected

Salary of Mike is 7500
Salary of Steve is 10000
Salary of Tom is 2000

```

## 填充关联数组

填充一个密集型关联数组最有效的方式是使用 `SELECT [FETCH] BULK COLLECT INTO` 子句。

#### 说明

如果一个密集型关联数组要填充大量的内容，而使用 `SELECT` 语句返回的结果集会超出内存大小，则可以通过使用游标和 `FETCH` 语句并结合 `BULK COLLECT INTO` 和 `LIMIT` 子句，以代替 `SELECT` 语句。

填充一个稀疏型关联数组时不能使用 `SELECT` 语句，可以在 `FOR LOOP` 循环语句里使用赋值语句。

下面示例是使用 `SELECT` 语句填充按整型索引的关联数组，然后使用 `FOR LOOP` 语句填充一个按字符串索引的稀疏型关联数组。

**示例：填充关联数组**

```javascript
obclient> CREATE TABLE emp(
     emp_id NUMBER NOT NULL);
Query OK, 0 rows affected

obclient>INSERT INTO emp VALUES(101),(102),(103),(103),(102);
Query OK, 5 rows affected
Records: 5  Duplicates: 0  Warnings: 0

obclient>DECLARE
     TYPE num_table IS TABLE OF emp.emp_id%TYPE
                  INDEX BY BINARY_INTEGER;     -- 定义关联数组的索引类型是整型
     num_list NUM_TABLE;                 -- 定义关联数组的变量

BEGIN
     SELECT emp_id
     BULK COLLECT INTO num_list from emp;
     DBMS_OUTPUT.PUT_LINE('Bulk Collected:');

    FOR i IN num_list.FIRST..num_list.LAST LOOP
     IF i <= 3 THEN
        DBMS_OUTPUT.PUT_LINE('Number ['||num_list(i)||']');
     END IF;
   END LOOP;
END;
/

Query OK, 0 rows affected

Bulk Collected:
Number [101]
Number [102]
Number [103]

```

## 遍历密集型关联数组

密集型关联数组（按整型索引）的元素之间没有空隙，每个位于第一个和最后一个元素之间的元素都有定义和值（这个值可以是 `NULL`），可以使用 `FOR LOOP` 语句遍历一个密集型关联数组。

下面示例使用 `FOR LOOP` 语句去打印关联数组的每个元素值。其中，`FOR LOOP` 语句的上限 `tab _wares.COUNT` 调用了集合的方法 `COUNT` 返回数组中元素数目。

**示例：遍历密集型关联数组**

```javascript
obclient> CREATE TABLE ware (
        w_id            INT NOT NULL,
        w_name      VARCHAR(10),
        w_city          VARCHAR(20),
        w_state        VARCHAR(20),
         PRIMARY KEY(w_id)
         );
Query OK, 0 rows affected
obclient>INSERT INTO ware VALUES(1,'KING','BeiJing','China');
Query OK, 1 row affected
obclient>INSERT INTO ware VALUES(2,'ALLEN','ShangHai','China');
Query OK, 1 row affected
obclient>INSERT INTO ware VALUES(3,'CLARK','ShangHai','China');
Query OK, 1 row affected

obclient>SET SERVEROUTPUT ON;
Query OK, 0 rows affected

obclient>DECLARE
    -- 声明关联数组，不带游标
    TYPE type_ware IS TABLE OF ware%ROWTYPE INDEX BY PLS_INTEGER ;
    tab_wares   TYPE_WARE;
    TYPE type_ware_city IS TABLE OF ware.w_city%TYPE INDEX BY VARCHAR(20);
    tab_ware_cities TYPE_WARE_CITY;
    TYPE  type_ware_name IS TABLE OF ware.w_name%TYPE INDEX BY VARCHAR(20);
    ware_names  TYPE_WARE_NAME;
BEGIN
   SELECT w_id,w_name,w_city,w_state BULK COLLECT INTO tab_wares FROM ware;

    FOR i IN 1..tab_wares.COUNT LOOP
       dbms_output.put_line(
           rpad( tab_wares(i).w_id, 23)
           || rpad( tab_wares(i).w_name, 23)
           || rpad(tab_wares(i).w_city, 23 )
            );
     END LOOP;
END;
/
Query OK, 0 rows affected

1                      KING                   BeiJing
2                      ALLEN                  ShangHai
3                      CLARK                  ShangHai

```

## 遍历稀疏型关联数组

稀疏型关联矩阵（按字符串索引）在元素之间可能存在空隙，需要使用 `WHILE LOOP` 语句结合集合的方法 `FIRST` 和 `NEXT` 来遍历稀疏型关联数组。示例如下：

```javascript
DECLARE
    -- 声明关联数组，不带游标
    TYPE type_ware IS TABLE OF ware%ROWTYPE INDEX BY PLS_INTEGER ;
    tab_wares   TYPE_WARE;
    TYPE type_ware_city IS TABLE OF ware.w_city%TYPE INDEX BY VARCHAR(20);
    tab_ware_cities TYPE_WARE_CITY;
    TYPE  type_ware_name IS TABLE OF ware.w_name%TYPE INDEX BY VARCHAR(20);
    -- 在声明部分增加：
    i_name  ware.w_name%TYPE;

BEGIN
   SELECT w_id,w_name,w_city,w_state
    BULK COLLECT INTO tab_wares FROM ware;

    FOR i IN 1..tab_wares.COUNT LOOP
       dbms_output.put_line(
           rpad( tab_wares(i).w_id, 23)
           || rpad( tab_wares(i).w_name, 23)
           || rpad(tab_wares(i).w_city, 23 )
            );
     END LOOP;
    -- 在执行部分增加：
    i_name := tab_ware_cities.FIRST ;
      WHILE i_name IS NOT NULL LOOP
           dbms_output.put_line(rpad(i_name,12) || tab_ware_cities(i_name) );
        i_name := tab_ware_cities.NEXT(i_name);
      END LOOP;
END;
/
Query OK, 0 rows affected

```

 上一篇 下一篇 ![有帮助](https://gw.alipayobjects.com/mdn/ob_asset/afts/img/A*y6ocSqN8cqsAAAAAAAAAAAAAARQnAQ)![无帮助](https://gw.alipayobjects.com/mdn/ob_asset/afts/img/A*BG9IQJyLHF8AAAAAAAAAAAAAARQnAQ)![反馈](https://gw.alipayobjects.com/mdn/ob_asset/afts/img/A*eTWdQKCRKHwAAAAAAAAAAAAAARQnAQ)[AI](https://www.oceanbase.com/obi) 咨询热线
