关键字:
KingbaseES、PLSQL、RECORD
1.记录类型概述
记录(RECORD)数据类型是KingbaseES的PLSQL中支持的一种复合数据类型。 在普通的标量数据中,一个变量只能存储一个一维的数据。而RECORD类型可以存储多维的数据,例如,可以将一个表中的完整一行或者一行中部分列抽取出来,存储在一个RECORD类型的变量中。由于RECORD类型跟表中的行具有类似的数据结构,因此通过RECORD类型可以方便地对表中的行进行操作,例如,可以通过向表中插入一个RECORD类型的变量来实现插入行的动作,也可以通过RECORD来更新表中的行。
2.记录类型的声明和定义
(1)方式一:
可以使用以下语句声明一个名为rec_type的RECORD类型:
TYPE rec_type IS RECORD (a NUMBER, b NUMBER);
其中,a和b表示rec_type的两个属性值,它们的数据类型都是NUMBER。如果将一个rec_type变量看做一个表中的一行的话,那么a和b就表示该行中的字段。在上面的声明形式中,rec_type和括号里面的内容是用户自定义的,其余的3个标识符都是固定的,rec_type表示用户给一个RECORD类型取的名字,而括号里面的内容则表示该RECORD类型具有的各个属性,例如上面的a和b, 每个属性都由一个数据类型来描述,例如a为NUMBER类型,这里的数据类型不仅可以是普通的标量数据类型,如INT, VARCHAR等,也可以是复杂的复合数据类型,如可变数组,另一个RECORD类型等。
在声明了一个RECORD类型后,可以使用下面的语句来定义一个RECORD变量point。
point rec_type := (0,1); 、 该语句表明变量point是一个rec_type类型的变量,并且该变量第一个属性(字段)的值为1,第二个属性(字段)的值为2。
(2)方式二
可以使用%ROWTYPE来声明一个RECORD变量。例如
stu_rec student%ROWTYPE;
其中,student是一个已经创建的表名。该语句定义了一个RECORD类型的变量stu_rec,它的每个字段都和student表中一行的字段是一致的。
(3)方式三
可以借助游标来定义一个表示表中部分字段的RECORD变量。例如
\set SQLTERM /
DECLARE
CURSOR c IS SELECT id, name FROM student;
stu c%ROWTYPE;
BEGIN
NULL
END;
/
在上面的程序块中,假设student是一个含有3个字段id, name, score的一张表,那么,借助游标c定义的RECORD变量stu只表示了student表中的部分字段id和name。 另外,如果只是声明了一个RECORD类型的变量,而没有对其进行初始化赋值时,它的每个属性(字段)的初始值都是NULL。RECORD类型的变量之间也不能用来比较,即在RECORD类型的变量之间不可以使用“IS NULL”,“>”, “=”等这样的比较运算符。
3.记录类型的常见用法
(1)通过RECORD变量来向表中插入数据
当使用RECORD变量向表中插入行时,该RECORD变量必须表示对应表中的行。下面的示例展示了如何使用RECORD变量向表中插入数据的用法。
\set SQLTERM ;
DROP TABLE IF EXISTS schedule;
CREATE TABLE schedule (
week NUMBER,
Mon VARCHAR2(10),
Tue VARCHAR2(10),
Wed VARCHAR2(10),
Thu VARCHAR2(10),
Fri VARCHAR2(10),
Sat VARCHAR2(10),
Sun VARCHAR2(10)
);
\set SQLTERM /
DECLARE
/*使用%ROWTYPE来定义一个RECORD变量default_week, 它跟schedule表中的行具有相同的数据结构*/
default_week schedule%ROWTYPE;
BEGIN
/*给RECORD变量default_week的字段赋值*/
default_week.Mon := '0900-1800';
default_week.Tue := '0900-1800';
default_week.Wed := '0900-1800';
default_week.Thu := '0900-1800';
default_week.Fri := '0900-1800';
default_week.Sat := 'Day Off';
default_week.Sun := 'Day Off';
/*使用循环语句和RECORD变量default_week来向schedule表中插入4行数据*/
FOR i IN 1..4 LOOP
default_week.week := i;
INSERT INTO schedule VALUES default_week;
END LOOP;
END;
/
\set SQLTERM ;
SELECT * FROM schedule;
执行结果:
week | mon | tue | wed | thu | fri | sat | sun
------+-----------+-----------+-----------+-----------+-----------+---------+---------
1 | 0900-1800 | 0900-1800 | 0900-1800 | 0900-1800 | 0900-1800 | Day Off | Day Off
2 | 0900-1800 | 0900-1800 | 0900-1800 | 0900-1800 | 0900-1800 | Day Off | Day Off
3 | 0900-1800 | 0900-1800 | 0900-1800 | 0900-1800 | 0900-1800 | Day Off | Day Off
4 | 0900-1800 | 0900-1800 | 0900-1800 | 0900-1800 | 0900-1800 | Day Off | Day Off
(4 rows)
(2)通过RECORD变量来更新表中的行
PL/SQL扩展了SQL中的UPDATE语句, 以支持通过RECORD变量来更新表中的行。当使用RECORD变量更新表中的行时,该RECORD变量必须能够表示对应表中的行。在上一小节示例中已建好并插入了数据的schedule表的基础上,下面的示例展示了如何使用RECORD变量来更新表中的行。
\set SQLTERM /
DECLARE
/*使用%ROWTYPE来定义一个RECORD变量default_week, 它跟schedule表中的行具有相同的数据结构*/
update_week schedule%ROWTYPE;
BEGIN
/*给RECORD变量update_week的字段赋值*/
update_week.Mon := 'Day Off';
update_week.Tue := 'Day Off';
update_week.Wed := '0800-1700';
update_week.Thu := '0800-1700';
update_week.Fri := '0800-1700';
update_week.Sat := '0800-1700';
update_week.Sun := '0800-1700';
/*使用循环语句和RECORD变量update_week通过PLSQL扩展过的UPDATE语句来更新schedule表中的2行数据*/
FOR i IN 1..2 LOOP
update_week.week := i;
UPDATE schedule
SET ROW = update_week
WHERE week = i;
END LOOP;
END;
/
\set SQLTERM ;
SELECT * FROM schedule order by week;
执行结果:
week | mon | tue | wed | thu | fri | sat | sun
------+-----------+-----------+-----------+-----------+-----------+-----------+-----------
1 | Day Off | Day Off | 0800-1700 | 0800-1700 | 0800-1700 | 0800-1700 | 0800-1700
2 | Day Off | Day Off | 0800-1700 | 0800-1700 | 0800-1700 | 0800-1700 | 0800-1700
3 | 0900-1800 | 0900-1800 | 0900-1800 | 0900-1800 | 0900-1800 | Day Off | Day Off
4 | 0900-1800 | 0900-1800 | 0900-1800 | 0900-1800 | 0900-1800 | Day Off | Day Off
(4 rows)