【Oracle】第五章游标和触发器(一)

2015-02-03 04:03:44 · 作者: · 浏览: 37

第五章游标和触发器

游标:

隐式游标:%FOUND, %NOTFOUND ,%ROWCOUNT

1.%FOUND 用法,只有在DML 语句影响一行或者多行时,%FOUND 属性才返回 TRUE。下列示例演示了 %FOUND 的用法:

begin

update employees2 set first_name = 'scott' where employee_id = 2;

if SQL%found then

dbms_output.put_line('数据已经更新');

-- dbms_output.put_line('rowCount = '||mrowcount);

else

dbms_output.put_line('数据没有找到');

end if;

end;

/

以下代码演示了创建了一个游标,返回employees2 表中 salary 大于300000 的记录,注意type 的使用:

declare

csalary employees2.salary%type;

cursor emp2_cursor is select salary from employees2 where salary >300000;

begin

open emp2_cursor ;

loop

fetch emp2_cursor into csalary;

exit when emp2_cursor%notfound;

dbms_output.put_line('csalary = '||csalary);

end loop;

end;

/

以下代码演示了创建了一个游标,返回employees2 表中 division_id=’SAL’ 的记录。

注意rowtype 的使用:

declare

cursor employee2_cursor is select * from employees2 where division_id='SAL';

myrecord employees2%rowtype;

begin

open employee2_cursor;

fetch employee2_cursor into myrecord;

while employee2_cursor%found loop

dbms_output.put_line('employee id ='||myrecord.employee_id);

dbms_output.put_line('first Name ='||myrecord.first_name);

dbms_output.put_line('last name ='||myrecord.last_name);

fetch employee2_cursor into myrecord;

end loop;

end;

/

以下代码演示了带参数的游标,根据division id 查询指定的记录:

declare

myrecord employees2%rowtype;

cursor emp_cursor(divisionid varchar2) is select * from employees2 where division_id =divisionid;

begin

open emp_cursor('&divisionid');

--loop

fetch emp_cursor into myrecord;

while emp_cursor%found loop

-- exit when emp_cursor%notfound;

dbms_output.put_line('employee id = '||myrecord.employee_id);

dbms_output.put_line('division id = ' ||myrecord.division_id);

dbms_output.put_line('first name = ' ||myrecord.first_name);

fetch emp_cursor into myrecord;

end loop;

close emp_cursor;

end;

/

以下代码演示了在创建游标时指定更新表中的字段。更新 employees2 表中的 first_name 字段:

set serveroutput on

declare

firstName varchar2(20);

cursor employees2_cursor is select first_name from employees2 where employee_id=1 for update of

first_name;

begin

open employees2_cursor;

loop

fetch employees2_cursor into firstName;

exit when employees2_cursor%notfound;

update employees2

set first_Name='jeff ' where current of employees2_cursor;

end loop;

close employees2_cursor;

commit;

end; /

触发器:

触发器是当特定事件出现时自动执行的存储过程

特定事件可以是执行更新的DML语句和DDL语句

触发器不能被显式调用

触发器的功能:

自动生成数据

自定义复杂的安全权限

提供审计和日志记录

启用复杂的业务逻辑

触发器的类型包括:行级触发器,语句级触发器、INSTEAD OF 触发器、模式触发器、数据库级触发器。

创建触发器语法:

CREATE [OR REPLACE] TRIGGER trigger_name

AFTER | BEFORE | INSTEAD OF

[INSERT] [[OR] UPDATE [OF column_list]]

[[OR] DELETE]

ON table_or_view_name

[REFERENCING {OLD [AS] old / NEW [AS] new}]

[FOR EACH ROW]

[WHEN (condition)]

pl/sql_block;

创建行级触发器,以下代码演示了插入或者修改 employees2 表中的first_name 如果等于 ‘scott’时触发器就会执行:

create or replace trigger tri_employees2

before insert or update of first_name

on employees2

referencing NEW as newdata OLD as olddata

for each row

when (newdata.first_name='scott')

begin

: newdata.salary :=20000;

dbms_output.put_line('new.salary:' || :newdata.salary);

dbms_output.put_line('old.salary:' || :olddata.salary);

end;

执行以上触发器:

insert into employees2 values(38,'SUP','WOR','scott','mp',50000);

或者:

update employees2 set salary=90000,first_name='scott' where employee_id=38;

以下代码针对数据完整性进行操作(删除dept 表中的ID 同时把外键表emp