---
title: "记录 - OceanBase 数据库 V4.6.0 | OceanBase 文档中心"
description: 记录 记录类型是把逻辑相关的数据作为一个单元存储起来，至少包括一个标量型或 RECORD 数据类型的成员，称作 PL RECORD 的域（ FIELD ），其作用是存放互不相同但逻辑相关的信息。 功能适用性 该内容仅适用于 OceanBase 数据库企业版。OceanBase 数据库社区版暂不支持。 记录变量的初始值…
---
切换语言

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

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

# 记录

更新时间：2026-04-30 18:36:40

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

记录类型是把逻辑相关的数据作为一个单元存储起来，至少包括一个标量型或 `RECORD` 数据类型的成员，称作 PL `RECORD` 的域（`FIELD`），其作用是存放互不相同但逻辑相关的信息。

#### 功能适用性

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

## 记录变量的初始值

对于 `RECORD` 类型的记录变量，每个字段的初始值为 `NULL`，除非在定义类型时为其指定了不同的初始值。

对于用 `%ROWTYPE` 或 `%TYPE` 声明的记录变量，每个字段的初始值为 `NULL`。该变量不继承所引用项目的初始值。

## 声明记录常量

声明记录常量时，必须先创建一个函数，并对记录初始化，然后在常量声明中调用该函数。

如下例所示：

```shell
obclient> CREATE OR REPLACE PACKAGE my_rec_types IS
  TYPE rec IS RECORD (a NUMBER, b NUMBER,k NUMBER);
  FUNCTION init_rec RETURN rec;
END my_rec_types;
/
Query OK, 0 rows affected

obclient> CREATE OR REPLACE PACKAGE BODY my_rec_types IS
  FUNCTION init_rec RETURN rec IS
    c_rec REC;
  BEGIN
    c_rec.a := 111;
    c_rec.b := 222;
    c_rec.k := 333;
    RETURN c_rec;
  END init_rec;
END my_rec_types;
/
Query OK, 0 rows affected

obclient> DECLARE
  r CONSTANT my_rec_types.rec := my_rec_types.init_rec();
BEGIN
  DBMS_OUTPUT.PUT_LINE('r.a = ' || r.a);
  DBMS_OUTPUT.PUT_LINE('r.b = ' || r.b);
  DBMS_OUTPUT.PUT_LINE('r.k = ' || r.k);
END;
/
Query OK, 0 rows affected

r.a = 111
r.b = 222
r.k = 333

```

## 记录类型

在 PL 块中定义的 `RECORD` 类型是本地类型。

包头中定义的 `RECORD` 类型是公有 `RECORD` 类型。通过使用 `package_name.type_name` 限定包的名称，可以从包外部引用它。它存储在数据库中，使用 `DROP PACKAGE` 语句删除程序包时会一起删除 `RECORD` 类型。

您不能在 `Schema` 级别创建 `RECORD` 类型。因此，`RECORD` 类型不能是 ADT 属性数据类型。

定义 `RECORD` 类型时，需要指定其名称并定义其字段类型。要定义字段，需要指定其名称和数据类型。默认情况下，字段的初始值为 `NULL`。您可以为字段指定 `NOT NULL` 约束，在这种情况下，初始值必须非 `NULL`。如果没有 `NOT NULL` 约束，初始值没有非 `NULL` 的限制。

包头中定义的 `RECORD` 类型与具有相同定义的本地 `RECORD` 类型不兼容。

定义 `RECORD` 变量类型时可以使用存储过程所支持的数据类型，或者使用 `%TYPE` 方法复制表或者游标列的类型。示例如下：

```sql
DECLARE
   TYPE region_record_type IS RECORD (
       id REGIONS.region_id%TYPE,
       name REGIONS.region_name%TYPE
   );
   region_record region_record_type;

```

在 OceanBase 数据库中，记录支持与其他复杂类型嵌套使用，包括集合、数组等。

如下示例为带有 Varray 字段的 `RECORD` 类型。

```sql
DECLARE
  TYPE empname IS VARRAY(3) OF VARCHAR2(20);

  TYPE contact IS RECORD (
    name  empname := empname('Zhang','San','Feng'),  -- Varray 字段
    phone employees.phone_number%TYPE
  );
  emp contact;
BEGIN
   emp.phone := '123456789';
   DBMS_OUTPUT.PUT_LINE (
         emp.name(1) || ' ' ||
         emp.name(2) || ' ' ||
         emp.name(3) || ', ' ||
         emp.phone
   );
END;/
Query OK, 0 rows affected

Zhang San Feng, 123456789

```

## 记录变量

记录变量包括单个记录变量和复合记录变量。

您可以分别为记录变量的每个字段赋值。在某些情况下，也可以将一个记录变量的值赋值给另一个记录变量。如果记录变量表示数据库表或视图的全部或部分行，则可以将所代表的行赋值给记录变量。

### 将记录变量赋值给另一个

仅当满足如下条件时才可以将一个记录变量的值赋值给另一记录变量：

- 两个变量具有相同的 `RECORD` 类型。
 - 如果目标变量是以 `RECORD` 类型明确声明的，而源变量是使用 `％ROWTYPE` 通过表的行类型声明的，则要求两者的字段数量和顺序必须完全一致。并且，相互对应的每个字段也必须具备相同的数据类型。

**使用构造函数直接为记录类型变量赋值的示例如下**：

```sql
DECLARE
  TYPE employee_record_type IS RECORD (
    id employee.id%TYPE,
    name employee.name%TYPE,
    salary employee.salary%TYPE
  );
  -- 使用构造函数语法赋值
  v_employee_rec employee_record_type := employee_record_type(1, 'John Doe', 55000.00);
BEGIN
  -- 此处可以使用 v_employee_rec 变量
  DBMS_OUTPUT.PUT_LINE('Employee: ' || v_employee_rec.name || ', Salary: ' || v_employee_rec.salary);
END;
/

```

**单独为每个字段赋值的示例如下**：

```sql
DECLARE
  -- 声明记录类型，指示它的字段将与employee表的结构相同。
  v_employee_rec employee%ROWTYPE;
BEGIN
  -- 单独为每个字段赋值
  v_employee_rec.id := 1;
  v_employee_rec.name := 'John Doe';
  v_employee_rec.salary := 55000.00;
  -- 打印输出记录中的信息
  DBMS_OUTPUT.PUT_LINE('Employee: ' || v_employee_rec.name || ', Salary: ' || v_employee_rec.salary);
END;
/

```

### 为记录变量分配全部或部分行

如果记录变量表示数据库表或视图的全部或部分行，则可以将对应的行分配给记录变量。方法如下：

- 使用 `SELECT INTO` 将行赋值给记录变量

  简单的 `SELECT INTO` 声明的语法是：

  ```sql
  SELECT select_list INTO record_variable_name FROM table_or_view_name;

  ```

  对于 `select_list` 中的每一列，记录变量必须具有一个对应的并与其类型兼容的字段。`select_list` 中列的顺序必须与记录字段的顺序相同。
 - 使用 `FETCH` 将行赋值给记录变量

  简单的 `FETCH` 声明的语法为：

  ```sql
  FETCH cursor INTO record_variable_name;

  ```

  游标与查询相关联。对于查询选择的每一列，记录变量必须具有一个对应的并与其类型兼容的字段。游标必须是显式游标或强类型游标变量。
 - 使用 SQL 语句返回 PL 记录变量中的行

  `RETURNING INTO` 子句指定存储该子句所属语句返回的值的变量。带有 `RETURNING INTO` 子句的`INSERT`、`UPDATE` 和 `DELETE` SQL 语句可以返回 PL 记录变量中的行数据。

### 将 NULL 赋值给记录变量

将 `NULL` 赋值给记录变量的同时会将 `NULL` 值赋值给它的每个字段。

此赋值是递归的，如果某一个字段是一条记录，那么它的字段也将被赋值为 `NULL`。

## 创建记录

记录的内部组件称为字段，访问记录的字段时，需要使用符号"."，格式为： ***记录名.字段名***。

创建记录的方式包括有以下三种：

- 声明一个 `RECORD` 类型，然后声明该类型的变量。语法如下：

  ```sql
  TYPE record_name IS RECORD
  ( field_name data_type [:= initial_value]
  [, field_name data_type [:= initial_value ] ]... );

  variable_name record_name;

  ```
 - 声明一个变量、类型并与表的行类型关联。语法如下：

  ```sql
  variable_name table_name%ROWTYPE ;

  ```

  #### 说明

  记录的字段跟表的列名字和数据类型一一对应。
 - 声明一个变量、类型并与游标的类型关联。语法如下：

  ```sql
  variable_name cursor_name%ROWTYPE ;

  ```

  #### 说明

  记录的字段要与游标的 `SELECT` 查询里的列的名字和数据类型一一对应。

  示例如下：

  ```sql
  obclient> DECLARE
      TYPE my_rec IS RECORD(
            code VARCHAR2(10),
            name VARCHAR2(50) NOT NULL :='book');
      v_book MY_REC;
  BEGIN
      v_book.code :='10000';
      v_book.name :='OceanBase PL Developer Guide';
      DBMS_OUTPUT.PUT_LINE(v_book.code||': '||v_book.name);
  END;
  /
  Query OK, 0 rows affected

  10000: OceanBase PL Developer Guide

  ```

  #### 说明

  对记录变量的操作和普通变量相同，可以用 `SELECT INTO` 语句对其进行赋值。

 上一篇 下一篇 ![有帮助](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) 咨询热线
