PostgreSQL中支持RECORD和TABLE_NAME%ROWTYPE两种行类型,两种类型使用上有一些区别。
- RECORD: 记录变量类似于行类型变量,但是它们没有预定义的结构,只能通过SELECT或FOR命令来获取实际的行结构,因此记录变量在被初始化之前无法访问,否则将引发运行时错误。(注:RECORD不是真正的数据类型,只是一个占位符)。
- TABLE_NAME%ROWTYPE: 行数据类型,通过使用TABLE_NAME%ROWTYPE标记,一个行变量可以被声明为具有和一个现有表或视图的行相同的类型。它也可以通过给定一个组合类型名称来声明(因为每一个表都有一个相关联的具有相同名称的组合类型,所以在PostgreSQL中实际上写不写%ROWTYPE都没有关系。但是带有%ROWTYPE的形式可移植性更好)。
RECORD类型
PostgreSQL中支持另一种行类型:record,这种类型在定义时不必指定具体字段和类型。
// 定义方式
DECLARE
rec1 record;
rec2 record;
// 在使用时,record的内部结构由赋值时指定。用于接收一行数据,作用等同于TABLE_NAME%ROWTYPE
select id,name,age into rec1 from table1;
select id,name,age into rec2 from table2;
TABLE_NAME%ROWTYPE类型
PostgreSQL定义函数时,支持定义行类型,即可以完全继承表的行定义。
ROWTYPE内部的字段名与表保持严格一致,且在定义后就完全继承表的字段名了。
// 定义方式
DECLARE
row1 table1%ROWTYPE;
row2 table2%ROWTYPE;
// 把查询table1、table2的结果赋值给row1、row2
select id,name,age into row1 from table1;
select id,name,age into row2 from table2;
RECORD示例
create table demo(
t1 int,
t2 varchar
);
insert into demo values(1,'t1');
insert into demo values(2,'t2');
insert into demo values(3,'t3');
insert into demo values(4,'t4');
insert into demo values(5,'t5');
insert into demo values(6,'t6');
CREATE OR REPLACE PROCEDURE getdemo()
AS $BODY$
DECLARE
rec record;
BEGIN
for rec in select t1 as id,t2 as name from demo
loop
raise notice 'rec.id: %', rec.id;
raise notice 'rec.t2: %', rec.name;
end loop;
END; $BODY$
LANGUAGE plpgsql;
//输出
> 注意: rec.id: 1
> 注意: rec.t2: t1
> 注意: rec.id: 2
> 注意: rec.t2: t2
> 注意: rec.id: 3
> 注意: rec.t2: t3
> 注意: rec.id: 4
> 注意: rec.t2: t4
> 注意: rec.id: 5
> 注意: rec.t2: t5
> 注意: rec.id: 6
> 注意: rec.t2: t6
从示例结果来看有两点结论:
- RECORD变量内部字段名会受结果集影响,字段名与结果集保持一致
- RECORD变量内部字段的赋值,也是按结果集顺序赋值的
TABLE_NAME%ROWTYPE示例
create table demo(
t1 int,
t2 varchar
);
insert into demo values(1,'t1');
insert into demo values(2,'t2');
insert into demo values(3,'t3');
insert into demo values(4,'t4');
insert into demo values(5,'t5');
insert into demo values(6,'t6');
CREATE OR REPLACE PROCEDURE getdemo()
AS $BODY$
DECLARE
row demo%ROWTYPE;
BEGIN
for row in select t1 as id,t2 as name from demo
loop
raise notice 'row.t1: %', row.t1;
raise notice 'row.t2: %', row.t2;
end loop;
END; $BODY$
LANGUAGE plpgsql;
//输出
> 注意: row.t1: 1
> 注意: row.t2: t1
> 注意: row.t1: 2
> 注意: row.t2: t2
> 注意: row.t1: 3
> 注意: row.t2: t3
> 注意: row.t1: 4
> 注意: row.t2: t4
> 注意: row.t1: 5
> 注意: row.t2: t5
> 注意: row.t1: 6
> 注意: row.t2: t6
从示例结果来看有两点结论:
- ROWTYPE变量内部字段名不会受结果集影响,与表字段保持一致
- ROWTYPE变量内部字段的赋值,是按结果集顺序赋值的,与结果集中的字段名无关