跳转到主内容
新派编程网 - 新潮编程理念,全新技术课堂!

如何定义记录类型_TYPE IS RECORD自定义多字段结构

TYPE IS RECORD 的基本语法为 TYPE 类型名 IS RECORD (字段名 类型 [DEFAULT 值] [NOT NULL]);,支持标量、%TYPE、嵌套记录,作用域限于当前块或包;不可整体比较或判空,赋值为值拷贝;INSERT/UPDATE 中可用但须字段顺序严格匹配。 怎么写 TYPE IS RECORD 的基本语法 直接用
type
关键字加
is record
块就能定义,字段名、类型、默认值、
not null
约束都写在括号里,不依赖表结构也能用。
TYPE
名称自己起,作用域只在当前 PL/SQL 块(比如
DECLARE
段)或包内,不能跨过程直接复用 字段类型支持标量(
VARCHAR2(50)
)、引用(
employees.salary%TYPE
)、甚至嵌套记录(另一个
RECORD
类型) 可以给字段设默认值:
timeout NUMBER DEFAULT 30
,但注意:只有声明变量时才生效,
SELECT INTO
或赋值后不会回填默认值 带
NOT NULL
的字段,一旦没初始化或赋值就访问,会报
ORA-06502: PL/SQL: numeric or value error
什么时候该用 RECORD 而不是 %ROWTYPE 当你要组合的字段来自多张表、视图、计算列,或者根本没对应物理表时,
%ROWTYPE
就不管用了,必须手写
TYPE IS RECORD
。 比如封装接口入参:一个订单操作要传
order_id
、
status_code
(查码表得来)、
processed_at
(
SYSDATE
计算),这三者不在同一张表里 又比如做轻量 DTO:把查询结果加工成含描述字段(如
dept_name
替代
dept_id
)的结构,避免后续反复
JOIN
%ROWTYPE
是“照抄表结构”,字段增删会导致 RECORD 定义失效;而自定义 RECORD 更稳定,改字段只需同步改一处声明 赋值和比较的常见翻车点
RECORD
支持整体赋值(
r2 := r1
),但绝不支持整体比较或判空——这是新手最常栽跟头的地方。 ❌ 错误写法:
IF r1 = r2 THEN ...
→ 编译失败,报
PLS-00306: wrong number or types of arguments
✅ 正确做法:逐字段比,
IF r1.id = r2.id AND r1.name = r2.name THEN ...
❌ 不能写
IF r1 IS NULL THEN
→ 语法错误,记录类型没有整体空值语义 ✅ 判空只能字段级:
IF r1.id IS NULL OR r1.name IS NULL THEN
注意:整体赋值是值拷贝,修改
r2
不会影响
r1
;但若 RECORD 里有
REF CURSOR
或对象类型,行为会不同(极少见,一般避开) 能不能在 INSERT / UPDATE 里直接用 RECORD 变量 能,但有严格限制:必须字段顺序、数量、类型完全匹配目标表,且不能含虚拟列或只读列。 插入:用
INSERT INTO t VALUES v_rec
,前提是
v_rec
的字段顺序和
t
的列顺序一致(不是名字匹配) 更新整行:用
UPDATE t SET ROW = v_rec WHERE ...
,同样要求字段顺序对齐;如果只想更新部分字段,还是老实用
SET col1 = v_rec.col1, col2 = v_rec.col2
别指望用 RECORD 绕过约束:如果表有
NOT NULL
列而
v_rec
对应字段是
NULL
,DML 一样报错 性能上无额外开销,本质还是展开成字段列表,但可读性提升明显——尤其字段多、逻辑分组清晰时 真正麻烦的是嵌套 RECORD 或动态字段数场景,这时候就得换
CREATE TYPE
对象类型,或者干脆用关联数组(
TABLE OF RECORD
)+ 批量 DML。但日常单行结构封装,
TYPE ... IS RECORD
已经够稳、够快、够直白。

相关文章