首批通过分布式安全可靠测评,为关键业务系统打造
记录
更新时间:2026-03-26 17:56:44
记录类型是把逻辑相关的数据作为一个单元存储起来,至少包括一个标量型或 RECORD 数据类型的成员,称作 PL RECORD 的域(FIELD),其作用是存放互不相同但逻辑相关的信息。
功能适用性
该内容仅适用于 OceanBase 数据库企业版。OceanBase 数据库社区版暂不支持。
记录变量的初始值
对于 RECORD 类型的记录变量,每个字段的初始值为 NULL,除非在定义类型时为其指定了不同的初始值。
对于用 %ROWTYPE 或 %TYPE 声明的记录变量,每个字段的初始值为 NULL。该变量不继承所引用项目的初始值。
声明记录常量
声明记录常量时,必须先创建一个函数,并对记录初始化,然后在常量声明中调用该函数。
如下例所示:
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 方法复制表或者游标列的类型。示例如下:
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 类型。
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通过表的行类型声明的,则要求两者的字段数量和顺序必须完全一致。并且,相互对应的每个字段也必须具备相同的数据类型。
使用构造函数直接为记录类型变量赋值的示例如下:
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;
/
单独为每个字段赋值的示例如下:
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声明的语法是:SELECT select_list INTO record_variable_name FROM table_or_view_name;对于
select_list中的每一列,记录变量必须具有一个对应的并与其类型兼容的字段。select_list中列的顺序必须与记录字段的顺序相同。使用
FETCH将行赋值给记录变量简单的
FETCH声明的语法为:FETCH cursor INTO record_variable_name;游标与查询相关联。对于查询选择的每一列,记录变量必须具有一个对应的并与其类型兼容的字段。游标必须是显式游标或强类型游标变量。
使用 SQL 语句返回 PL 记录变量中的行
RETURNING INTO子句指定存储该子句所属语句返回的值的变量。带有RETURNING INTO子句的INSERT、UPDATE和DELETESQL 语句可以返回 PL 记录变量中的行数据。
将 NULL 赋值给记录变量
将 NULL 赋值给记录变量的同时会将 NULL 值赋值给它的每个字段。
此赋值是递归的,如果某一个字段是一条记录,那么它的字段也将被赋值为 NULL。
创建记录
记录的内部组件称为字段,访问记录的字段时,需要使用符号".",格式为: 记录名.字段名。
创建记录的方式包括有以下三种:
声明一个
RECORD类型,然后声明该类型的变量。语法如下:TYPE record_name IS RECORD ( field_name data_type [:= initial_value] [, field_name data_type [:= initial_value ] ]... ); variable_name record_name;声明一个变量、类型并与表的行类型关联。语法如下:
variable_name table_name%ROWTYPE ;说明
记录的字段跟表的列名字和数据类型一一对应。
声明一个变量、类型并与游标的类型关联。语法如下:
variable_name cursor_name%ROWTYPE ;说明
记录的字段要与游标的
SELECT查询里的列的名字和数据类型一一对应。示例如下:
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语句对其进行赋值。