关♥生活,关注互联网。
《数据库(oracle 10g)开发技术》课程实验及参考答案
一、 实验目的
《数据库开发技术》课程之实验六
PL/SQL 复合数据类型:记录、表和可变数组
1. 掌握如何创建 PL/SQL 记录 。
2. 会用%ROWTYPE 属性创建一个记录。
3. 掌握如何创建 PL/SQL 表和记录表。
4. 掌握那些能获得复合数据信息的内置方法的使用。
5. 掌握可变数组的使用。
二、 实验内容和要求
1. 根据表 emp 的全部字段定义记录变量 emp_record。用 SELECT 语句将编号为 7788 的雇员的全部字
段对应地存入该记录变量,最后输出记录变量的雇员名称字段 emp_record.ename 和雇员工资字段
的内容。
SET SERVEROUTPUT ON
DECLARE
emp_record emp%ROWTYPE; –定义记录变量
BEGIN
SELECT * INTO emp_record
FROM emp
WHERE empno = 7788; –取出一条记录
DBMS_OUTPUT.PUT_LINE(emp_record.ename||’的工资为:’||
To_char(emp_record.sal)); –输出记录变量的某个字段
END;
执行结果如下:
SCOTT 的工资为:3000
PL/SQL 过程已成功完成。
2. 声明一张 Index_By 表,用来接收并存储 DEPT 表的信息,把部门号作为键,不要忘记部门号是 10
的倍数。使用循环从 DEPT 表中将所有部门信息检索到 PL/SQL 记录表中,然后用另一个循环来显
示表中的这些信息。
DECLARE
TYPE dept_list_type IS TABLE OF dept%ROWTYPE index by binary_integer;
dept_list dept_list_type;
v_count number(3);
BEGIN
SELECT count(*) INTO v_count FROM dept;
FOR counter IN 1..v_count LOOP
SELECT * INTO dept_list(counter*10) FROM dept
WHERE deptno=counter*10;
END LOOP;
FOR COUNTER IN 1..v_count LOOP
DBMS_OUTPUT.PUT_LINE(to_char(dept_list(counter*10).deptno)||’, ‘||
dept_list(counter*10).dname||’, ‘||dept_list(counter*10).loc);
END LOOP;
END;
/
执行结果为:
10, ACCOUNTING, NEW YORK
20, RESEARCH, DALLAS
30, SALES, CHICAGO
40, OPERATIONS, BOSTON
PL/SQL 过程已成功完成。
3. 阅读以下程序,找出出错之处,说明出错原因,预测运行输出结果是什么。请删改错误,加上适当
注释后,运行该程序,验证自己的预测是否正确。(注:实验报告中只要指出出错的语句和出错的原因
即可,不要抄原程序!)
SET SERVEROUTPUT ON
DECLARE
TYPE dept_list IS TABLE OF dept.dname%TYPE; –定义嵌套表
TYPE top5_list IS VARRAY(5) OF dept.loc%TYPE; –定义可变数组
dis_dept dept_list; –嵌套表的声明
num_5 top5_list; –可变数组的声明
BEGIN
/* 下 面的这 条 dis_dept(1):=’AMGN’ 赋值 语句是 非 法的, 因为 集合 尚未初始 化。出 现错 误提示
(ORA-06531: 引用未初始化的集合,是以下 ORA-06531 Reference to uninitialized collection 的翻
译)。集合变量的初始化是通过调用集合的构造函数来实现的,集合构造函数与集合对象(而不是集合
变量)同名。改正的方法有二。一是在集合变量声明的同时进行初始化,例如:
dis_dept dept_list :=dept_list(‘AMGN’, ‘BGEN’); 也可以在变量声明之后再进行初始化,例如:
dis_dept dept_list;
……
dis_dept :=dept_list(‘AMGN’,’BGEN’);
本题则可以直接将下面的这条 dis_dept(1):=’AMGN’ 语句删除即可。
*/
— dis_dept(1):=’AMGN’;
IF dis_dept IS NULL THEN
–显式调用构造函数进行集合的初始化
dis_dept :=dept_list(‘AMGN’,’BGEN’);
DBMS_OUTPUT.PUT_LINE(‘dis_dept 表当前元素个数为:’||to_char(dis_dept.count));
END IF;
num_5:=top5_list(‘ORCL’,’CSCO’,NULL,NULL);
IF num_5(3) IS NULL THEN
num_5(3):=’CPQ’;
END IF;
num_5(4):=’DELL’;
FOR COUNTER IN 1..4 LOOP
DBMS_OUTPUT.PUT_LINE(NUM_5(COUNTER));
END LOOP;
END;
/
执行结果为:
dis_dept 表当前元素个数为:2
ORCL
CSCO
CPQ
DELL
PL/SQL 过程已成功完成。
以下是另一个相关的例子:
SET SERVEROUTPUT ON
DECLARE
TYPE dept_list IS TABLE OF dept.dname%TYPE; –定义嵌套表
TYPE top5_list IS VARRAY(5) OF dept.loc%TYPE; –定义可变数组
dis_dept dept_list; –嵌套表的声明
num_5 top5_list; –可变数组的声明
v_count number(3);
BEGIN
IF dis_dept IS NULL THEN
–嵌套表要显式调用构造函数进行集合的初始化
dis_dept :=dept_list(‘AMGN’,’BGEN’);
DBMS_OUTPUT.PUT_LINE(‘dis_dept 表当前元素个数为:’||to_char(dis_dept.count));
dis_dept.extend(2);
dis_dept(3):=’EXTEND_ELEMENT’;
v_count:=dis_dept.count;
–嵌套表必须使用 extend(n)动态增加元素
DBMS_OUTPUT.PUT_LINE(‘dis_dept 表扩充后的元素个数为:’||to_char(dis_dept.count));
FOR i IN 1.. v_count loop –输出嵌套表 dis_dept 的内容
DBMS_OUTPUT.PUT_LINE(dis_dept(i));
END LOOP;
END IF;
num_5:=top5_list(‘ORCL’,’CSCO’,NULL,NULL);
IF num_5(3) IS NULL THEN
num_5(3):=’CPQ’;
END IF;
num_5(4):=’DELL’;
FOR COUNTER IN 1..4 LOOP
DBMS_OUTPUT.PUT_LINE(NUM_5(COUNTER));
END LOOP;
END;
/
执行结果为:
dis_dept 表当前元素个数为:2
dis_dept 表扩充后的元素个数为:4
AMGN
BGEN
EXTEND_ELEMENT
ORCL
CSCO
CPQ
DELL
PL/SQL 过程已成功完成。
4. *将上题改为使用 INDEX BY BINARY_INTEGER 的索引表,则实现同一执行结果,程序要做哪些
相应的改变。
DECLARE
TYPE dept_list IS TABLE OF dept.dname%TYPE index by binary_integer; –定义索引组织表
TYPE top5_list IS VARRAY(5) OF dept.loc%TYPE;
dis_dept dept_list;
num_5 top5_list;
BEGIN
dis_dept(1):=’AMGN’; –为表元素赋值
IF not dis_dept.exists(2) THEN
dis_dept(2) :=’BGEN’;
DBMS_OUTPUT.PUT_LINE(‘dis_dept 表当前元素个数为:’||to_char(dis_dept.count));
END IF;
num_5:=top5_list(‘ORCL’,’CSCO’,NULL,NULL);
IF num_5(3) IS NULL THEN
num_5(3):=’CPQ’;
END IF;
num_5(4):=’DELL’;
FOR COUNTER IN 1..4 LOOP
DBMS_OUTPUT.PUT_LINE(NUM_5(COUNTER));
END LOOP;
END;
/
执行结果为:
dis_dept 表当前元素个数为:2
ORCL
CSCO
CPQ
DELL
PL/SQL 过程已成功完成。
以下是与上题对应的另一个相关的例子:
SET SERVEROUTPUT ON
DECLARE
TYPE dept_list IS TABLE OF dept.dname%TYPE index by binary_integer; –定义索引组织表
TYPE top5_list IS VARRAY(5) OF dept.loc%TYPE; –定义可变数组
dis_dept dept_list; –索引表的声明
num_5 top5_list; –可变数组的声明
v_count number(3);
BEGIN
dis_dept(1):=’AMGN’; –为表元素赋值
IF not dis_dept.exists(2) THEN
DBMS_OUTPUT.PUT_LINE(‘dis_dept 表当前元素个数为:’||to_char(dis_dept.count));
— dis_dept.extend(2);
dis_dept(3):=’EXTEND_ELEMENT’;
v_count:=dis_dept.count;
–索引表无须使用 extend(n)增加元素,使用了反而出错
DBMS_OUTPUT.PUT_LINE(‘dis_dept 表增添元素后的个数为:’||to_char(dis_dept.count));
FOR i IN 1.. v_count loop
DBMS_OUTPUT.PUT_LINE(dis_dept(i));
END LOOP;
END IF;
num_5:=top5_list(‘ORCL’,’CSCO’,NULL,NULL);
IF num_5(3) IS NULL THEN
num_5(3):=’CPQ’;
END IF;
num_5(4):=’DELL’;
FOR COUNTER IN 1..4 LOOP
DBMS_OUTPUT.PUT_LINE(NUM_5(COUNTER));
END LOOP;
END;
/
执行结果为:
dis_dept 表当前元素个数为:2
dis_dept 表增添元素后的个数为:3
AMGN
BGEN
EXTEND_ELEMENT
ORCL
CSCO
CPQ
DELL
PL/SQL 过程已成功完成。
附加题:
*分割省份信息放入嵌套表结构中。用户输入:湖南|河南|江西,按”|”分割省份。
1) 接受用户输入
2) 分割字符串,把省份分割出放入嵌套表结构中
3) 遍历输出嵌套表
提示:str := ‘&STR’ — str:= ‘湖南|河南|江西’;
SET SERVEROUTPUT ON
DECLARE
TYPE prov_type IS TABLE OF varchar(15); –定义嵌套表
prov_list prov_type:=prov_type(); –嵌套表的声明与初始化
str varchar(150);
v_loc number(3);
v_count number(2):=1;
BEGIN
str:= ‘&STR’; — str:= ‘湖南|河南|江西’;
LOOP
v_loc :=instr(str,’|’,1);
prov_list.extend;
IF v_loc=0 THEN
prov_list(v_count):=str;
EXIT;
ELSE
prov_list(v_count):=substr(str,1,v_loc-1);
str:=substr(str,v_loc+1);
v_count:=v_count+1;
END IF;
END LOOP;
DBMS_OUTPUT.PUT_LINE(‘用户输入的省份显示如下:’);
FOR i IN 1.. v_count loop –输出嵌套表 prov_list 的内容
DBMS_OUTPUT.PUT_LINE(prov_list(i));
END LOOP;
END;
/
5. 参照教材和课件中的相关例子,自选实例使用复合数据的各种内置方法。
三、 实验报告
根据实验内容要求写出相应的 PL/SQL 程序,并记录实验过程中遇到的困难和解决问
题的方法。(实验报告中不要求写加*题目和附加题的实验过程和内容)