更新时间:2026-10-21 GMT+08:00
record
record类型的变量
定义一个record类型 ,然后使用该类型来声明一个变量,该变量即为record变量。
语法
定义record类型的语法为:
TYPE type_name IS_RECORD (field_declaration [,...] );
语法图如图1所示。
其中field_declaration为:
field_name datatype [ [NOT_NULL] { := | DEFAULT } expression] field_declaration语法图如图2所示。
对以上语法格式的解释如下:
- 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
父主题: 数组、集合和record

