Oracle讲解
WHILE num>0 LOOP
SELECT COUNT(*) INTO num FROM score WHERE courseId=21 AND score<60; UPDATE score SET score=100 WHERE score>=95 AND courseId=21; UPDATE score SET score=score+5 WHERE score<95 AND courseId=21; END LOOP; COMMIT; END;
PL/SQL块出
//如果以上现死循环,会导致score表被锁定,需要这样解锁 首先用conn system/system登录系统 使用:
select p.spid,c.object_name,a.serial#,b.session_id,b.oracle_username,b.os_user_name from v$process p,v$session a, v$locked_object b,all_objects c where p.addr=a.paddr and a.process=b.process and c.object_id=b.object_id; 查看被锁定的对象。 然后通过
alter system kill session ‘session_id,serial#’; 其中session_id,serial#是取下面的那条记录。 解除锁定。
FOR 计数器 IN value1..value2 LOOP 语句; END LOOP;
SET SERVEROUTPUT ON; DECLARE n NUMBER(2):=0; BEGIN FOR n IN 1..10 LOOP DBMS_OUTPUT.PUT_LINE('accp'); END LOOP; END; /
顺序控制:
GOTO语句无条件将控制权转到标签指定的语句,标签是用<< accp >> 表示的 NULL语句什么都不做将控制权转到下一个语句
3.3 预定义异常
BEGIN 语句; EXCEPTION
16
Oracle讲解
WHEN 异常名称 THEN 语句;
WHEN OTHERS THEN 语句; END;
系统自带的异常在此省略
用户自定义异常
SET SERVEROUTOUT ON; DECLARE myException EXCEPTION; BEGIN IF(条件)
Oracle游标
4.1 隐式游标
%FOUND
只有在DML语句影响一行或多行时,%FOUND属性才返回TRUE SET SERVEROUTPUT ON BEGIN
UPDATE student SET studentId=2 where studentId=1; IF SQL%FOUND THEN
DBMS_OUTPUT.PUT_LINE(‘表已更新’); ELSE
DBMS_OUTPUT.PUT_LINE(‘编号未找到’); END IF; END;
%NOTFOUND 与%FOUND属性的作用相反。
%ROWCOUNT
返回DML语句影响的函数。如果没有影响任何行,则返回0 %ISOPEN
返回游标是否已经打开,在执行SQL后Oracle自动关闭SQL游标,所以隐式游标的%ISOPEN属性始终为FALSE。
17
Oracle讲解
4.2显示游标
是由用户显示声明的游标。4个步骤来使用显示游标 1:声明游标 2:打开游标
3:从游标中获取记录 4:关闭游标
CURSOR 游标名称 [输入参数] [定义游标提取的行的类型] IS 指定游标使用的查询语句 控制游标可以使用 OPEN 打开游标
OPEN 游标名称[参数] FETCH 从游标中获取行 FETCH 游标名称 INTO 变量 常写在循环里,每次提取记录后就会向下移动一行 CLOSE 关闭游标 在处理完游标的所有行之后,必须关闭
4.3 使用游标查询
18
Oracle讲解
SET SERVEROUTPUT ON DECLARE
stuName student.stuName%TYPE; CURSOR stu_cus IS SELECT stuName FROM student WHERE stuId>6; BEGIN
OPEN stu_cus; LOOP FETCH stu_cus INTO stuName; EXIT WHEN stu_cus%NOTFOUND; DBMS_OUTPUT.PUT_LINE(stu_cus%ROWCOUNT || ‘,学员姓名:’ || stuName); END LOOP; CLOSE stu_cus; END; /
使用显示游标删除或更新
将成绩小于60分的学员成绩修改成60分,在定义游标的时必须使用SELECT…FOR UPDATE语句,而在执行DELETE和UPDATE时使用WHERE CURRENT OF子句指定游标的当前行。
SET SERVEROUTPUT ON DELCARE
new_Score NUMBER; CURSOR cur_stu IS
SELECT score FROM student WHERE score<60 FOR UPDATE OF score; BEGIN
OPEN cur_stu; LOOP
FETCH score INTO new_Score; UPDATE student SET score=60 WHERE CURRENT OF cus_stu; END LOOP; CLOSE cus_stu; END;
带参数的显示游标 DECLARE
stuId student.stu_Id%TYPE;
stuName student.stu_stuName%TYPE; CURSOR cus_stu (stuAge NUMBER) IS
SELECT stu_Id,stu_Name FROM student WHERE stu_Age stuAge:=&学生年龄 OPEN cus_stu(stuAge); 19 Oracle讲解 LOOP FETCH cus_stu INTO stuId,stuName; EXIT WHEN cus_stu%NOTFOUND; DBMS_OUTPUT.PUT_LINE(‘’); END LOOP; CLOSE cus_stu; END; / 练习:输入empNo的值,使用带参数的显示游标求出所有empNo大于指定参数的记录 SET SERVEROUTPUT ON; DECLARE empnum NUMBER; cur_row emp%ROWTYPE; CURSOR my_emp(emp_No number) IS SELECT * FROM EMP WHERE empNo>emp_No; BEGIN empnum:=&输入编号; OPEN my_emp(empnum); LOOP FETCH my_emp INTO cur_row; EXIT WHEN my_emp%NOTFOUND; DBMS_OUTPUT.PUT_LINE('编号'||cur_row.empNo); END LOOP; CLOSE my_emp; END; / 循环游标 从循环游标提取所以行之后自动终止 提取和处理游标中的每一条记录 如果%NOTFOUNT返回TRUE,则终止循环。 SET SERVEROUTPUT ON; DECLARE CURSOR my_emp IS SELECT * FROM EMP; BEGIN FOR emp_rec IN my_emp LOOP DBMS_OUTPUT.PUT_LINE('编号'||emp_rec.empNo); END LOOP; END; / 说明:其中emp_rec是%ROWTYPE类型的变量,自动定义的,不能再FOR外面访问。 20