Oracle PL/SQL 记录类型及示例

⚡ 智能摘要

PL/SQL 记录类型是一种复杂的数据类型,它将多个列(每个列都有自己的名称和数据类型)组合成一个新的类型。记录可以在数据库级别定义为存储对象,也可以在子程序中定义,其字段可通过点运算符访问。

  • 🧱 定义: 记录类型将一个或多个列组合成一个新的数据类型。
  • ???? 关键词: TYPE 关键字告诉编译器正在创建一个新的数据类型。
  • 🏛️ 两级: 数据库级记录是存储的对象;子程序级记录仅在该子程序内部可见。
  • 🔗 实地考察: 使用点运算符,通过 record_variable.column_name 访问字段。
  • 📥 列级别: 一次只能为一个字段赋值。
  • 📦 行级别: SELECT INTO 语句可以从表的一行中填充整个记录。
  • 🧩 记录类型: 基于表的 %ROWTYPE、基于游标的 %ROWTYPE 和程序员定义的记录。

Oracle PL/SQL 记录类型

什么是记录类型?

记录类型是一种复杂的数据类型,它允许程序员创建具有所需列结构的新数据类型。其主要特点是:

  • 它将一列或多列组合在一起,形成一种新的数据类型。
  • 每一列都有自己的名称和数据类型。
  • 记录类型可以接受由多列组成的单个记录的数据,也可以接受记录中某一特定列的值。
  • 记录类型其实就是一种新的数据类型。创建后,它会作为一种新的数据类型存储,并可用于在程序中声明变量。
  • 它使用了关键字 '类型' 指示编译器正在创建新的数据类型。
  • 它可以在以下位置创建: 数据库级别存储为数据库对象并在整个数据库中使用,或在 子程序级仅在子程序内部可见。
  • 也可以为表列声明数据库级别的记录类型,以便单个列可以保存复杂数据。
  • 访问数据的方法是:先引用变量名,然后是句点运算符(.),最后是列名,例如: 。 '。

声明记录类型的语法

数据库级别声明的语法:

数据库级别的记录类型声明

CREATE TYPE <type_name_db> IS RECORD
(
<column 1> <datatype>,
);

在第一种语法中,关键字“CREATE TYPE”指示编译器创建名为“type_name_db”的记录类型,并将其作为数据库对象存储,列名由指定的字段决定。该语句是单独给出的,不包含在任何代码块中。

子程序级别声明的语法:

子程序级别的记录类型声明

DECLARE
TYPE <type_name> IS RECORD
(
<column1> <datatype>,
);
BEGIN
<execution_section>;
END;

在这种语法中,我们仅在子程序内部创建名为“type_name”的记录类型。两种方法中定义列和数据类型的方式类似。

示例 1:记录类型作为数据库对象

在本程序中,我们将学习如何创建数据库对象类型的记录。我们创建了名为“emp_det”的记录类型,它包含四列。各列及其数据类型如下:

  • EMP_NO(数字)
  • EMP_NAME (VARCHAR2 (150))
  • 经理(人数)
  • 薪资(数字)
CREATE TYPE emp_det IS OBJECT
(
EMP_NO NUMBER,
EMP_NAME VARCHAR2(150),
MANAGER NUMBER,
SALARY NUMBER
);
/

输出:

Type created

Code 说明

  • 上述代码创建了 emp_det 类型的数据库对象。
  • 它有 4 列:emp_no、emp_name、manager 和 salary,定义如下。
  • 现在,'emp_det' 与任何其他值类似。 数据类型 (例如 NUMBER 或 VARCHAR2)并且在整个数据库中可见。因此,可以在数据库的任何位置使用它来声明这种类型的变量。

示例 2:子程序级别、列级别访问

在这个示例中,我们将学习如何在子程序级别创建记录类型,以及如何按列填充和提取该记录类型的值。我们将在子程序级别创建“emp_det”记录类型,并使用它来填充和显示数据。

记录类型列级访问示例

DECLARE
TYPE emp_det IS RECORD
(
EMP_NO NUMBER,
EMP_NAME VARCHAR2(150),
MANAGER NUMBER,
SALARY NUMBER
);
guru99_emp_rec emp_det;
BEGIN
guru99_emp_rec.emp_no:= 1001;
guru99_emp_rec.emp_name:= 'XXX';
guru99_emp_rec.manager:= 1000;
guru99_emp_rec.salary:= 10000;
dbms_output.put_line('Employee Detail');
dbms_output.put_line ('Employee Number: '||guru99_emp_rec.emp_no);
dbms_output.put_line ('Employee Name: '||guru99_emp_rec.emp_name);
dbms_output.put_line ('Employee Salary: ' ||guru99_emp_rec.salary);
dbms_output.put_line ('Employee Manager Number: '||guru99_emp_rec.manager);
END;
/

输出:

Employee Detail
Employee Number: 1001
Employee Name: XXX
Employee Salary: 10000
Employee Manager Number: 1000

Code 说明

  • Code 第 2-8 行: 记录类型“emp_det”声明包含列emp_no、emp_name、manager和salary,数据类型分别为NUMBER、VARCHAR2、NUMBER和NUMBER。
  • Code 第9行: guru99_emp_rec 变量被声明为 'emp_det' 数据类型。 变量 可以包含包含所有四个字段的值。
  • Code 第11行: 用值 99 填充“guru1001_emp_rec”的“emp_no”字段。
  • Code 第12行: 将“emp_name”字段的值填充为XXX。
  • Code 第13行: 将“经理”字段的值填充为 1000。
  • Code 第14行: 将“薪水”字段的值填充为 10000。
  • Code 第 15-19 行: 在输出中显示“guru99_emp_rec”的值。

示例 3:子程序级、行级访问

在这个示例中,我们将看到如何在子程序级别创建记录类型,并在行级别填充数据。我们在子程序级别创建“emp_det”记录类型,并使用它来填充和显示数据。

记录类型行级访问示例

DECLARE
TYPE emp_det IS RECORD
(
EMP_NO NUMBER,
EMP_NAME VARCHAR2(150),
MANAGER NUMBER,
SALARY NUMBER
);
guru99_emp_rec emp_det;
BEGIN
INSERT INTO emp (emp_no, emp_name, salary, manager) VALUES (1002,'YYY',15000,1000);
COMMIT;
SELECT emp_no, emp_name, salary, manager INTO guru99_emp_rec FROM emp WHERE emp_no=1002;
dbms_output.put_line ('Employee Detail');
dbms_output.put_line ('Employee Number: '||guru99_emp_rec.emp_no);
dbms_output.put_line ('Employee Name: '||guru99_emp_rec.emp_name);
dbms_output.put_line ('Employee Salary: '||guru99_emp_rec.salary);
dbms_output.put_line ('Employee Manager Number: '||guru99_emp_rec.manager);
END;
/

Code 说明

  • Code 第 2-8 行: 记录类型“emp_det”声明包含列emp_no、emp_name、manager和salary,数据类型分别为NUMBER、VARCHAR2、NUMBER和NUMBER。
  • Code 第9行: guru99_emp_rec 变量被声明为 'emp_det' 数据类型,可以保存所有四个字段。
  • Code 第11行: 将 emp 表中的 emp_no 字段设置为 1002,emp_name 字段设置为 YYY,salary 字段设置为 15000,manager number 字段设置为 1000。
  • Code 第12行: 提交插入事务。
  • Code 第13行: 从员工编号为 1002 的选择查询中,在行级别填充“guru99_emp_rec”变量。
  • Code 第 15-19 行: 在输出中显示“guru99_emp_rec”的值。

输出:

Employee Detail
Employee Number: 1002
Employee Name: YYY
Employee Salary: 1000
Employee Manager Number: 15000

注意: 只有在将记录类型的值重定向到任何输出模式时,才能在列级别访问该记录类型。请注意,在本例中,SELECT 列表的顺序与记录字段的顺序不一致,这就是为什么输出中薪资和经理的值互换了。

PL/SQL 记录类型

除了上面所示的程序员定义的记录之外, Oracle 提供两种锚定记录类型,可自动复制其结构。使用它们可以避免重新声明列,并使记录与其所基于的表或游标保持同步。

记录类型 已声明 结构源于
基于表格的记录 表名%行类型 表中的所有列
基于游标的记录 cursor_name%ROWTYPE 光标的选择列表
程序员定义的记录 类型…是记录 您手动列出的列

当形状需要遵循表格或数组时,%ROWTYPE 记录是最安全的选择。 光标因为列更改会在下次编译时自动生效。

常见问题

记录将不同类型(可能不同)的列组合成一个类似行的结构。集合包含多个相同类型的元素,并用下标进行索引。它们通常组合在一起,构成记录集合。

%ROWTYPE 声明一条记录,其字段会自动与表或游标匹配。当记录需要反映源数据时,请使用此参数,以便在不编辑声明的情况下反映列更改。

是的,如果两条记录类型相同。SELECT INTO 也可以从表行中填充整条记录,前提是选择列表的顺序与记录的字段顺序匹配。

是的。AI 可以读取表定义并生成匹配的 TYPE … IS RECORD 块,或者在需要直接链接到表的情况下推荐 %ROWTYPE。使用前请验证数据类型。

数据库级记录使用 CREATE TYPE 语句创建,并作为对象存储,在整个数据库中可见。子程序级记录在代码块内声明,并且仅存在于该子程序中。

总结一下这篇文章: