1.简答题
(1)
PL/SQL语言是Oracle数据库专用的一种高级程序设计语言,是对标准SQL语言进行了过程化扩展的语言。具有如下特点:
Ø 与
SQL语言紧密集成,所有的SQL语句在PL/SQL中都得到支持;
Ø 减小网络流量,提高应用程序的运行性能。
Ø 模块化的程序设计功能,提高系统可靠性。
Ø 服务器端程序设计,可移植性好。
(2)
PL/SQL程序的基本单元是语句块,所有的PL/SQL程序都是由语句块构成的,语句块之间可以相互嵌套,每个语句块完成特定的功能。
Ø 声明部分:以关键字DECLARE开始,BEGIN结束。主要用于声明变量、常量、数据类型、游标、异常处理名称以及本地(局部)子程序定义等。
Ø 执行部分:是PL/SQL块的功能实现部分,以关键字BEGIN开始,EXCEPTION或END结束(如果PL/SQL块中没有异常处理部分,则以END结束)。该部分通过变量赋值、流程控制、数据查询、数据操纵、数据定义、事务控制、游标处理等实现块的功能。
Ø 异常处理部分:以关键字EXCEPTION开始,END结束。该部分用于处理该块执行过程中产生的异常。
(3)
PL/SQL程序中的选择结构有两种类型,分别为IF系列和CASE系列。循环结构包括简单循环、WHILE循坏、FOR循环三种。
(4)
游标的作用是将数据库的中数据检索出来后缓存,可以被PL/SQL程序一行一行的读取并处理。支持一条、多条、零条记录的处理。游标的基本操作步骤为声明游标、打开游标、检索游标、关闭游标。
(5)
Oracle中的命名块经过编译后可以存储在数据库服务器端,供用户从不同的客户端调用。常用的命名块包括存储过程、函数、包和触发器。其中,过程用于实现某特定操作;函数用户将运行结果返回给用户;包是一系列过程、函数、常量等集合;触发器是特定的事件处理器,当特定的事件发生时,系统自动进行调用执行。
(6)
触发器包括DML触发器、INSTEAD-OF触发器和系统触发器。其中,DML触发器主要作用于表,其事件有INSERT、UPDATE、DELETE;INSTEAD-OF触发器主要主用于视图,其事件有INSERT、UPDATE、DELETE;系统触发器主要是DML事件和系统事件发生时调用的触发器,其中DML事件包括CREATE、DROP、ALTER等,系统事件包括LOGON、LOGOFF、STARTUP、SHUTDOWN、SERVERERROR等。
(7)
DML触发器执行顺序为:
Ø 如果存在,执行语句级前触发器。
Ø 对于受触发事件影响的每一个记录:
l 如果存在,执行行级前触发器;
l 执行当前记录的DML操作(触发事件);
l 如果存在,执行行级后触发器。
Ø 如果存在,执行语句级后触发器。
(8)
DML触发器中的语句级触发器是激发触发器的SQL语句不管涉及到多少记录,触发器只执行一次,而行级触发器是激发触发器的SQL语句涉及到多少记录,触发器就执行多少次。通常,如果要获取当前操作记录的信息,需要采用行级触发器,而如果需要获取整个操作之前或操作之后的信息,可以采用语句级触发器。
(9)
基于数据库的系统触发器是只要数据库中相应事件发生,触发器就执行,与用户没有关系;而模式级别的触发器只有特定用户操作中的特定事件发生时触发器才执行。
(10)
PL/SQL命名块可以一次编译多次执行,可以放在服务器端由不同客户端用户调用;而匿名块只能一次性执行,不能被其他用户调用。
2.实训题
(1)
DECLARE
CURSOR c_emp IS select * from emp;
BEGIN
FOR v_emp IN c_emp LOOP
DBMS_OUTPUT.PUT_LINE(v_emp.ename||' '||v_emp.empno||' '||v_emp.deptno||' '||v_emp.sal);
END LOOP;
END;
(2)
DECLARE
v_emp emp%ROWTYPE;
BEGIN
SELECT * INTO v_emp FROM EMP WHERE ename='SMITH';
DBMS_OUTPUT.PUT_LINE(v_emp.empno||' '||v_emp.sal||' '||v_emp.deptno);
EXCEPTION
WHEN NO_DATA_FOUND THEN
INSERT INTO EMP(EMPNO,ENAME,SAL,DEPTNO) VALUES(2007,'SMITH',1500,10);
WHEN TOO_MANY_ROWS THEN
FOR v IN (SELECT * FROM EMP WHERE ENAME='SMITH') LOOP
DBMS_OUTPUT.PUT_LINE(v.empno||' '||v.sal||' '||v.deptno);
END LOOP;
END;
(3)
CREATE OR REPLACE PROCEDURE SHOWSAL(p_empno emp.empno%type)
AS
v_sal emp.sal%TYPE;
BEGIN
SELECT sal INTO v_sal FROM emp WHERE empno=p_empno;
DBMS_OUTPUT.PUT_LINE(v_sal);
END;
begin
showsal(7844);
end;
(4)
CREATE OR REPLACE PROCEDURE UPDATESAL (p_empno emp.empno%TYPE)
AS
v_deptno
emp.deptno%TYPE;
v_inc emp.sal%TYPE;
BEGIN
SELECT deptno INTO v_deptno FROM emp WHERE empno=p_empno;
CASE v_deptno
WHEN 10 THEN v_inc:=150;
WHEN 20 THEN v_inc:=200;
WHEN 30 THEN v_inc:=250;
ELSE v_inc:=300;
END CASE;
UPDATE emp SET sal=sal+v_inc WHERE empno=p_empno;
END;
(5)
CREATE OR REPLACE FUNCTION fun_sal(p_empno emp.empno%type)
RETURN emp.sal%TYPE
AS
v_sal emp.sal%TYPE;
BEGIN
SELECT sal INTO v_sal FROM EMP WHERE empno=p_empno;
RETURN v_sal;
END;
(6)
CREATE OR REPLACE FUNCTION fun_avgsal(p_deptno emp.deptno%type)
RETURN emp.sal%type
AS
v_sal emp.sal%type;
BEGIN
SELECT AVG(SAL) INTO V_SAL FROM EMP WHERE DEPTNO=P_DEPTNO;
RETURN V_SAL;
END;
(7)
CREATE OR REPLACE FUNCTION fun_avg_sal(p_empno emp.empno%type)
RETURN emp.sal%type
AS
v_sal emp.sal%type;
BEGIN
SELECT AVG(SAL) INTO V_SAL FROM EMP WHERE DEPTNO=(select deptno from emp where empno=p_empno);
RETURN V_SAL;
END;
(8)
CREATE OR REPLACE PACKAGE PKG_EMP
AS
FUNCTION func_highsal(p_deptno emp.deptno%type) RETURN emp.sal%type;
PROCEDURE proc_highsal(p_deptno emp.deptno%type);
END;
CREATE OR REPLACE PACKAGE BODY PKG_EMP
AS
FUNCTION func_highsal(p_deptno emp.deptno%type)
RETURN emp.sal%type
AS
v_highsal emp.sal%type;
BEGIN
select max(sal) into v_highsal from emp where deptno=p_deptno;
return v_highsal;
END;
PROCEDURE proc_highsal(p_deptno emp.deptno%type)
AS
BEGIN
FOR v_emp IN (SELECT * FROM EMP WHERE deptno=p_deptno and sal=func_highsal(p_deptno)) LOOP
DBMS_OUTPUT.PUT_LINE(v_emp.empno||' '||v_emp.ename);
END LOOP;
END;
END;
BEGIN
pkg_emp.proc_highsal(10);
END;
(9)
CREATE OR REPLACE TRIGGER trg_emp
AFTER INSERT OR UPDATE OR DELETE
ON EMP
DECLARE
v_sal emp.sal%type;
v_count number;
BEGIN
SELECT AVG(SAL),COUNT(*) INTO V_SAL,V_COUNT FROM EMP;
DBMS_OUTPUT.PUT_LINE(V_SAL||' '||V_COUNT);
END;
(10)
CREATE OR REPLACE PACKAGE PKG_DEPTNO
AS
V_DEPTNO EMP.DEPTNO%TYPE;
V_SAL EMP.SAL%TYPE;
END;
CREATE OR REPLACE TRIGGER trg_updateemp
BEFORE UPDATE ON EMP
FOR EACH ROW
BEGIN
PKG_DEPTNO.V_SAL:=:NEW.SAL;
PKG_DEPTNO.V_DEPTNO:=:NEW.DEPTNO;
END;
CREATE OR REPLACE TRIGGER trg_statement
AFTER UPDATE ON EMP
DECLARE
v_highsal emp.sal%type;
v_lowsal emp.sal%type;
BEGIN
SELECT MAX(SAL),MIN(SAL) INTO v_highsal,v_lowsal
FROM EMP WHERE DEPTNO= PKG_DEPTNO.V_DEPTNO;
IF PKG_DEPTNO.V_SAL>v_highsal or pkg_deptno.v_sal<v_lowsal THEN
RAISE_APPLICATION_ERROR(-20001,'THE SAL IS BEYOND!');
END IF;
END;
3.选择题
(1)A
(2)B
(3)A、C、D
(4)A、E
(5)B、D
(6)C、E
(7)C
(8)A
(9)E
(10)A