更新时间:2026-10-21 GMT+08:00
分享

record

record类型的变量

定义一个record类型 ,然后使用该类型来声明一个变量,该变量即为record变量。

语法

定义record类型的语法为:

TYPE type_name IS_RECORD (field_declaration [,...] );

语法图如图1所示。

图1 定义record类型的语法

其中field_declaration为:

field_name datatype [ [NOT_NULL] { := | DEFAULT } expression]

field_declaration语法图如图2所示。

图2 field_declaration

对以上语法格式的解释如下:

  • type_name:声明的类型名称。
  • field_name:record类型中的成员名称。
  • datatype:record类型中成员的类型。
  • expression:设置默认值的表达式。

使用约束

在GaussDB中:

  • record类型的变量的赋值支持:
    • 在函数或存储过程的声明阶段,声明一个record类型,并且可以在该类型中定义成员变量。
    • 一个record变量到另一个record变量的赋值。
    • SELECT INTO和FETCH向一个record类型的变量中赋值。
    • 将一个NULL值赋值给一个record变量。
  • record类型构造器赋值时支持使用=>,约束如下:
    • record类型构造器赋值时使用=>功能,仅在兼容ORA模式数据库下(即sql_compatibility='ORA')支持。
    • 支持在package内部定义record类型。
    • record类型构造器赋值时使用=>功能,仅在入参赋值连续使用=>到结尾时支持,如record_name(elename1 => val1, elename2 => val2, elename3 => val3)或record_name(val1, elename2 => val2, elename3 => val3);不支持非连续使用=>赋值或者使用=>赋值时未到最后一个入参,如record_name(elename1 => val1, elename2 => val2, val3)或record_name(val1, elename2 => val2, val3)。
  • 不支持INSERT和UPDATE语句使用record变量进行插入数据和更新数据。
  • 不支持record类型的构造器作为函数或存储过程参数的默认值。
  • 如果成员有复合类型,在声明阶段不支持指定默认值,该行为同声明阶段的变量一样。
  • 如果成员有record类型,则内层record类型的默认值不支持传递至外层record类型中。
  • 设置GUC参数enable_recordtype_check_strict为on后,成员是record类型,且record类型有列具有NOT NULL属性或DEFAULT属性,在存储过程或PACKAGE编译时会报错。
  • 设置GUC参数enable_recordtype_check_strict为on后,当PACKAGE里有record类型,且record类型有列具有NOT NULL属性或DEFAULT属性会在创建或编译时报错。
  • 设置GUC参数enable_recordtype_check_strict为on后,存储过程里的record类型NOT NULL功能生效。
  • 设置GUC参数behavior_compat_options启用proc_outparam_override选项后:
    • 带有out出参且返回record的函数,支持在外部SQL使用SELECT、CALL调用,在存储过程内支持使用PERFORM、表达式调用。
    • 在函数直接返回未定义的record类型时,至少需要带有一个out参数;如果返回的是已经定义的record类型,则可以不带out参数。详见示例。
    • 带out出参返回复合类型或record的函数,需要保持函数的预期返回类型与实际返回类型一致。
  • 在INSERT INTO table_name VALUES record_var语法中,record_var仅支持record类型变量和单层数组嵌套的record类型变量,不支持多层数组嵌套的record类型变量。
  • PL/SQL中静态DDL语句不支持使用record类型变量和成员。
  • record变量整体赋值时,按照列的声明顺序依次进行赋值,若某个列在赋值时出现异常,已赋值的列不会回滚。

示例

-- 创建一个表,并插入一些数据。
gaussdb=# CREATE TABLE emp_rec(
gaussdb(#     empno NUMERIC(4,0) NOT NULL,
gaussdb(#     ename VARCHAR(10)
gaussdb(# );
NOTICE:  The 'DISTRIBUTE BY' clause is not specified. Using 'empno' as the distribution column by default.
HINT:  Please use 'DISTRIBUTE BY' clause to specify suitable data distribution column.
CREATE TABLE
gaussdb=# INSERT INTO emp_rec VALUES(111, 'aaa'), (222, 'bbb'), (333, 'ccc');
INSERT 0 3
-- 表定义如下。
gaussdb=# \d emp_rec
           Table "public.emp_rec"
 Column |         Type          | Modifiers 
--------+-----------------------+-----------
 empno  | numeric(4,0)          | not null
 ename  | character varying(10) |

-- 演示在函数中对record进行操作。
gaussdb=# CREATE OR REPLACE FUNCTION regress_record(p_w VARCHAR2) RETURNS VARCHAR2 AS $$
gaussdb$# DECLARE
gaussdb$#     -- 声明一个record类型。
gaussdb$#     TYPE rec_type IS RECORD (name  VARCHAR2(100), epno INT);
gaussdb$#     employer rec_type;
gaussdb$#     -- 使用%type声明record类型。
gaussdb$#     TYPE rec_type1 IS RECORD (name  emp_rec.ename%TYPE, epno INT :=10);
gaussdb$#     employer1 rec_type1;
gaussdb$#     -- 声明带有默认值的record类型。
gaussdb$#     TYPE rec_type2 IS RECORD (
gaussdb$#         name VARCHAR2 NOT NULL := 'SCOTT',
gaussdb$#         epno INT NOT NULL :=10
gaussdb$#     );
gaussdb$#     employer2 rec_type2;
gaussdb$#     CURSOR C1 IS  SELECT ename,empno FROM emp_rec ORDER BY 1 LIMIT 1;
gaussdb$# BEGIN
gaussdb$#     -- 对一个record类型的变量的成员赋值。
gaussdb$#     employer.name := 'WARD';
gaussdb$#     employer.epno = 18;
gaussdb$#     RAISE INFO 'employer name: % , epno:%', employer.name, employer.epno;
gaussdb$# 
gaussdb$#     -- 将一个record类型的变量赋值给另一个变量。
gaussdb$#     employer1 := employer;
gaussdb$#     RAISE INFO 'employer1 name: % , epno: %',employer1.name, employer1.epno;
gaussdb$# 
gaussdb$#     -- 将一个record类型变量赋值为NULL。
gaussdb$#     employer1 := NULL;
gaussdb$#     RAISE INFO 'employer1 name: % , epno: %',employer1.name, employer1.epno;
gaussdb$# 
gaussdb$#     -- 获取record变量的默认值。
gaussdb$#     RAISE INFO 'employer2 name: % ,epno: %', employer2.name, employer2.epno;
gaussdb$# 
gaussdb$#     -- 在for循环中使用record变量。
gaussdb$#     FOR employer IN SELECT ename,empno FROM emp_rec ORDER BY 1 LIMIT 1 LOOP 
gaussdb$#         RAISE INFO 'employer name: % , epno: %', employer.name, employer.epno;
gaussdb$#     END LOOP;
gaussdb$# 
gaussdb$#     -- 在select into中使用record变量。
gaussdb$#     SELECT ename,empno  INTO employer2 FROM emp_rec ORDER BY 1 LIMIT 1;
gaussdb$#     RAISE INFO 'employer name: % , epno: %', employer2.name, employer2.epno;
gaussdb$# 
gaussdb$#     -- 在cursor中使用record变量。
gaussdb$#     OPEN C1;
gaussdb$#     FETCH C1 INTO employer2;
gaussdb$#     RAISE INFO 'employer name: % , epno: %', employer2.name, employer2.epno;
gaussdb$#     CLOSE C1;
gaussdb$#     RETURN employer.name;
gaussdb$# END; $$
gaussdb-# LANGUAGE plpgsql;
CREATE FUNCTION

-- 调用该函数。
gaussdb=# CALL regress_record('abc');
INFO:  employer name: WARD , epno:18
INFO:  employer1 name: WARD , epno: 18
INFO:  employer1 name: <NULL> , epno: <NULL>
INFO:  employer2 name: SCOTT ,epno: 10
INFO:  employer name: aaa , epno: 111
INFO:  employer name: aaa , epno: 111
INFO:  employer name: aaa , epno: 111
 regress_record 
----------------
 aaa
(1 row)
-- 删除函数。
gaussdb=# DROP FUNCTION regress_record;
DROP FUNCTION
-- 删除表。
gaussdb=# DROP TABLE emp_rec;
DROP TABLE

-- 打开兼容性参数proc_outparam_override时,返回已定义的record类型,函数可以不需out参数。
gaussdb=# CREATE TYPE rec_type IS (c1 INT, c2 INT);
CREATE TYPE
gaussdb=# SET behavior_compat_options = 'proc_outparam_override';
SET
gaussdb=# CREATE OR REPLACE FUNCTION func(a in INT) RETURN rec_type IS
gaussdb$#     r rec_type;
gaussdb$# BEGIN
gaussdb$#     r.c1:=1;
gaussdb$#     r.c2:=1;
gaussdb$#     RETURN r;
gaussdb$# END;
gaussdb$# /
CREATE FUNCTION
gaussdb=# CALL func(0);
 c1 | c2 
----+----
  1 |  1
(1 row)
gaussdb=# DROP FUNCTION func;
DROP FUNCTION
gaussdb=# DROP TYPE rec_type;
DROP TYPE
-- 打开兼容性参数proc_outparam_override时,函数直接返回未定义的record类型时,至少需要带有一个out参数。
gaussdb=# SET behavior_compat_options = 'proc_outparam_override';
SET
gaussdb=# CREATE OR REPLACE FUNCTION func(a OUT INT) RETURN RECORD IS
gaussdb$#     TYPE rc IS RECORD(c1 INT, c2 INT);
gaussdb$#     r rc;
gaussdb$# BEGIN
gaussdb$#     r.c1 := 1;
gaussdb$#     r.c2 := 1;
gaussdb$#     a := 999;
gaussdb$#     RETURN r;
gaussdb$# END;
gaussdb$# /
CREATE FUNCTION
gaussdb=# CALL func(1);
 func  |  a  
-------+-----
 (1,1) | 999
(1 row)
gaussdb=# DROP FUNCTION func;
DROP FUNCTION

-- 创建ORA兼容模式数据库,并切换到此数据库。
gaussdb=#  CREATE DATABASE ora_compatible_db DBCOMPATIBILITY 'ORA';
CREATE DATABASE
gaussdb=#  \c ora_compatible_db;
Non-SSL connection (SSL connection is recommended when requiring high-security)
You are now connected to database "ora_compatible_db" as user "omm".
-- record在pkg内部定义,record构造器全部入参赋值使用=>,执行成功。
ora_compatible_db=# 
CREATE OR REPLACE PACKAGE pa_test1
AS
 PROCEDURE p_display1(a NUMBER, b  VARCHAR);
 TYPE t1 IS RECORD(va INT,vb INT);
 v1 t1;
END pa_test1;
/
ora_compatible_db=# 
CREATE OR REPLACE PACKAGE BODY pa_test1
AS
  PROCEDURE p_display1(a NUMBER, b  VARCHAR) AS
 BEGIN
  v1 := t1(va => 1, vb => 2);
  DBE_OUTPUT.PUT_LINE('pkg test1');
 END;
END pa_test1;
/
ora_compatible_db=# CALL pa_test1.p_display1(b => 'm', a => 1);
 p_display1 
------------

(1 row)
-- record在pkg内部定义,record构造器入参赋值未连续使用=>,提示错误。
ora_compatible_db=# 
CREATE OR REPLACE PACKAGE pa_test1
AS
 PROCEDURE p_display1(a NUMBER, b  VARCHAR);
 TYPE t1 IS RECORD(va INT,vb INT);
 v1 t1;
END pa_test1;
/
CREATE OR REPLACE PACKAGE BODY pa_test1
AS
  PROCEDURE p_display1(a NUMBER, b  VARCHAR) AS
 BEGIN
  v1 := t1(va => 1, 2);
  DBE_OUTPUT.PUT_LINE('pkg test1');
 END;
END pa_test1;
/
ora_compatible_db=# CALL pa_test1.p_display1(b => 'm', a => 1);
ERROR:  positional argument cannot follow named argument
LINE 1: SELECT "17347.t1"(va => 1, 2)
                                   ^
QUERY:  SELECT "17347.t1"(va => 1, 2)
CONTEXT:  referenced column: 17347.t1
PL/pgSQL function p_display1(numeric,character varying) line 2 at assignment
-- 切换回原数据库,并删除创建的数据库。
ora_compatible_db=# \c postgres;
Non-SSL connection (SSL connection is recommended when requiring high-security)
You are now connected to database "postgres" as user "omm".
gaussdb=# DROP DATABASE ora_compatible_db;
DROP DATABASE

相关文档