更新时间:2024-08-20 GMT+08:00
record
record类型的变量
创建一个record变量的方式:
定义一个record类型 ,然后使用该类型来声明一个变量。
语法
record类型的语法参见图1。
对以上语法格式的解释如下:
- record_type:声明的类型名称。
- field:record类型中的成员名称。
- datatype:record类型中成员的类型。
- expression:设置默认值的表达式。
在GaussDB中:
- record类型变量的赋值支持:
- 在函数或存储过程的声明阶段,声明一个record类型,并且可以在该类型中定义成员变量。
- 一个record变量到另一个record变量的赋值。
- SELECT INTO和FETCH向一个record类型的变量中赋值。
- 将一个NULL值赋值给一个record变量。
- record类型构造器赋值时支持使用=>,约束如下:
- record类型构造器赋值时使用=>功能,仅在兼容A模式数据库下(即sql_compatibility='A')支持。
- 支持在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类型中。
- set enable_recordtype_check_strict = on;后,成员是record类型,且record类型有列具有not null属性或default属性,在存储过程或PACKAGE编译时会报错。
- set enable_recordtype_check_strict = on;后,当PACKAGE里有record类型,且record类型有列具有not null属性或defalut属性会在创建或编译时报错。
- set enable_recordtype_check_strict = on;后,存储过程里的record类型not null功能生效。
- datatype可以为存储过程中定义record类型、数组类型和集合类型(匿名块不支持)。
- 打开guc参数 set behavior_compat_options = 'proc_outparam_override' ;后:
- 带有out出参且返回record的函数,支持在外部SQL使用SELECT、CALL调用,在存储过程内支持使用PERFORM、表达式调用。
- 在函数直接返回未定义的record类型时,至少需要带有一个out参数;如果返回的是已经定义的record类型,则可以不带out参数。详见示例。
- 带out出参返回复合类型或record的函数,需要保持函数的预期返回类型与实际返回类型一致。
示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 |
--创建一个表,并插入一些数据: gaussdb=# create table emp_rec( gaussdb(# empno numeric(4,0) not null, gaussdb(# ename varchar(10) gaussdb(# ); 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 -- 创建A兼容模式数据库,并切换到此数据库。 gaussdb=# CREATE DATABASE ora_compatible_db DBCOMPATIBILITY 'A'; 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