标量类型是经过预定义的,利用这些类型可以衍生出一些复合类型。
PL/SQL 包括PL/SQL 记录和PL/SQL集合两类复合数据类型,其中集合又可分为 联合数组、嵌套表和VARRAY 3种复合数据类型
1、PL/SQL记录
PL/SQL记录类似于高级语言中的结构,每个记录一般都包含多个成员,它可以看做是一组标量的组合结构。当使用PL/SQL记录时,首先需要在定义部分定义记录类型和记录变量,然后在执行部分引用该记录变量。需要注意,当引用PL/SQL记录成员时,必须要加记录变量作为前缀
(即“记录变量.记录成员”)
PL/SQL 记录的声明语法如下:
TYPE record_type_name IS RECORD
(filed1 type1 [NOT NULL] [:=expr1]
...
field2 typen [NOT NULL] [:=exprn]
)
其中,record_type_name是记录类型的名字。引用时必须定义相关的变量,记录只是类型(TYPE),而不是变量(VARIABLE)。例如:
SQL> select * from emp;
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
----- ---------- --------- ----- ----------- --------- --------- ------
7369 7369 CLERK 7902 1980/12/17 800.00 20
7499 ALLEN SALESMAN 7698 1981/2/20 1600.00 300.00 30
7521 WARD SALESMAN 7698 1981/2/22 1250.00 500.00 30
7566 JONES MANAGER 7839 1981/4/2 2975.00 20
7654 MARTIN SALESMAN 7698 1981/9/28 1250.00 1400.00 30
7698 BLAKE MANAGER 7839 1981/5/1 2850.00 30
7782 CLARK MANAGER 7839 1981/6/9 2450.00 10
7788 SCOTT ANALYST 7566 1987/4/19 3000.00 20
7839 KING PRESIDENT 1981/11/17 5000.00 10
7844 TURNER SALESMAN 7698 1981/9/8 1500.00 0.00 30
7876 ADAMS CLERK 7788 1987/5/23 1100.00 20
7900 JAMES CLERK 7698 1981/12/3 950.00 30
7902 FORD ANALYST 7566 1981/12/3 3000.00 20
7934 MILLER CLERK 7782 1982/1/23 1300.00 10
14 rows selected
SQL>
SQL> set feedback on;
SQL> set serveroutput on;
DECLARE
TYPE emp_record_type IS RECORD(
empno emp.empno%TYPE,
ename emp.ename%TYPE,
job emp.job%TYPE,
mgr emp.mgr%TYPE,
hiredate emp.hiredate%TYPE,
sal emp.sal%TYPE,
comm emp.comm%TYPE,
deptno emp.deptno%TYPE
);
emp_record emp_record_type;
BEGIN
SELECT empno,ename,job,mgr,hiredate,sal,comm,deptno INTO emp_record
FROM emp WHERE empno=7499;
dbms_output.put_line('序号-名称
'||emp_record.empno||'-'||emp_record.ename);
END;
SQL>
19 /
序号-名称
7499-ALLEN
PL/SQL procedure successfully completed
为了使PL/SQL代码中定义的变量,能与数据库中的某一列或某一行的数据类型相联系,
Oracle提供了%TYPE和%ROWTYPE的变量定义方式,在上例中,emp.ename%TYPE中的emp为表名,ename为emp表的一个列名。通过这种定义,emp_record_type的成员变量ename就与emp表的ename列建立了联系,即两者的数据类型一致。这样,当emp表的ename列的数据类型发生改变时,emp_record_type的成员变量ename的数据类型也会随之改变。
在上面的代码中,emp_record_type是PL/SQL记录类型,而且包含了ename,job,mgr等成员;emp_record是记录类型的变量;epm_record.ename表示引用记录变量emp_record的成员ename.
提示:DBMS_OUTPUT.PUT_LINE()函数只有SQL*PLUS客户端支持。
2、联合数组
联合数组是一个键值对的集合,它类似于高级语言中的数组,特别是Java中的哈希表,在处理方式上也相似。但需要注意,联合数组与高级语言的数组有所区别,例如,高级语言数组的下标不能为负值,但联合数组的下标可以为负值,高级语言数组的元素个数有限制,而联合数组的元素个数没有限制,并且其下标没有上下限,其声明语法如下:
TYPE table_type_name IS TABLE OF scalar_type INDEX BY index_datatype;
其中,table_type_name是类型的名字;scalar_type是一种标量类型的类型声明。引用时也必须定义相关的变量。表和数组不同,表有两列,即KEY和VALUE。其中,KEY就是定义时生命的index_datatype;VALUE就是定义时生命的scalar_type。
当使用联合数组时,首先必须在定义部分定义联合数组类型和联合数组变量,然后在执行部分中引用该联合数组变量。如下列所示:
DECLARE
TYPE emp_table_type IS TABLE OF emp.ename%TYPE INDEX BY BINARY_INTEGER;
emp_table emp_table_type;
BEGIN
SELECT ename INTO emp_table(0) FROM emp WHERE empno=7369;
dbms_output.put_line('名称'||emp_table(0));
END;
SQL> set serveroutput on;
SQL>
9 /
名称7369
PL/SQL procedure successfully completed
emp_table_type是联合数组类型:emp.ename%TYPE制定了联合数组元素的数据类型和长度;emp_table是联合数组类型变量;emp_table(0)即表示该表类型变量中下标为0的元素
3、嵌套表
嵌套表(Nested Table)与联合数组类似,但嵌套表可以走位表列的数据类型,但联合数组不能作为表列的数据类型。其声明语法如下:
TYPE table_name is TABLE OF table_type [NOT NULL];
嵌套表的声明和使用如下例所示:
CREATE OR REPLACE TYPE emp_type AS OBJECT
(
EMPNO NUMBER(4),
ENAME VARCHAR2(10),
JOB VARCHAR2(9),
MGR NUMBER(4),
HIREDATE DATE,
SAL NUMBER(7,2),
COMM NUMBER(7,2),
DEPTNO NUMBER(2)
);
DECLARE
TYPE empTbl IS TABLE OF emp_type;
v_tbl empTbl:=empTbl();
BEGIN
v_tbl.Extend;
v_tbl(v_tbl.Last):=emp_type(1, 'SMITH', 'CLERK', 7902, to_date('17-12-1980', 'dd-mm-yyyy'), 800, null, 20);
END;
SQL> SET SERVEROUTPUT ON;
SQL>
10 /
PL/SQL procedure successfully completed
对象类型emp_type用于存储信息,而empTbl是基于emp_type的嵌套表类型,它可以用于存储多种信息,当监理了嵌套表类型之后,就可以在表列或者兑现属性中将其作为用户自定义数据类型来引用。