---------------------------------------------------游标-------------------------------------------------------------
/*
1.游标分为:
1.显示游标(用于处理select语句返回的多行数据)
2.隐含游标(用户处理select...into 和 dml语句)
2.创建游标(分为4步)
1.定义游标:cursor 游标名 is select语句
2.打开游标:open 游标名;
3.提取数据:fetch 游标名 into 接收游标数据变量1,接收游标数据变量2,.。。。;
或者
fetch 游标名 bulk collect into 接收游标结果的集合变量1,接收游标结果的集合变量2,.。。
4.关闭游标
*/
--游标
--用游标循环打印部门编号为10的人员信息编号和名称
declare
cursor cursor_emp is select * from emp where deptno=10;
--声明一个变量用来接收游标取出的数据
t_emprow emp%rowtype;
begin
--打开游标
open cursor_emp;
loop
--取出游标的数据,放入行变量中
fetch cursor_emp into t_emprow;
--当游标取不到数据的时候,退出循环
exit when cursor_emp%notfound;
--打印
dbms_output.put_line('员工编号'||t_emprow.empno||'员工姓名'||t_emprow.ename);
end loop;
--关闭游标
close cursor_emp;
end;
--用table结构提取游标的数据(循环打印dept表里的数据)
declare
--定义一个table数据类型
type table_dept is table of dept%rowtype index by binary_integer;
--声明一个table类型具体变量
t_dept table_dept;
--声明游标
cursor cursor_dept is select * from dept;
begin
--打开游标
open cursor_dept;
--取出游标的数据
fetch cursor_dept bulk collect into t_dept;
--关闭游标
close cursor_dept;
for i in t_dept.first..t_dept.last loop
dbms_output.put_line('部门名称'||t_dept(i).dname||'位置是:'||t_dept(i).loc);
end loop;
end;
--打印指定部门编号的人员信息
select * from emp
declare
--声明一个游标
cursor cursor_emp(v_deptno number)
is select * from emp where deptno=v_deptno;
t_emprow emp%rowtype;
begin
--打开游标
open cursor_emp(&deptno);
loop
fetch cursor_emp into t_emprow;
exit when cursor_emp%notfound;
dbms_output.put_line('员工姓名'||t_emprow.ename||'雇佣日期'||to_char(t_emprow.hiredate,'yyyy-mm-dd'));
end loop;
close cursor_emp;
end;
--游标for循环
declare
cursor cursor_dept is select * from dept;
begin
for i in cursor_dept loop
dbms_output.put_line(i.dname||'===='||i.loc);
end loop;
end;
--游标for循环查询emp表前五条记录
declare
cursor emp_cursor is select * from emp;
type my_table_type is table of emp_cursor%rowtype index by binary_integer;
my_table my_table_type;
i number;
begin
open emp_cursor;
for i in 1..5 loop
fetch emp_cursor into my_table(i);
end loop;
close emp_cursor;
for i in 1..5 loop
dbms_output.put_line(my_table(i).empno||' '||my_table(i).ename||' '||my_table(i).job||' '||my_table(i).mgr||' '||my_table(i).hiredate||' '||my_table(i).sal||' '||my_table(i).comm||' '||my_table(i).deptno);
end loop;
end;
--------------------------------------------------触发器---------------------------------------------------------------
--语句级的触发器
--周一或周五不能修改emp表
create or replace trigger tri_emp
--before/after 事件发生前或后触发
before update on emp --不能修改,如果是增删改用or隔开就好(befor update or delete or insert on emp)
begin
if to_char(sysdate,'day') in ('星期一','星期日')then
raise_application_error(-20001,'星期一或日不能修改enp表');
end if;
end;
update emp set ename='ALLEN' where empno=7499;
select *from emp
--失效触发器
alter trigger tri_emp disable;
--启用触发器
alter trigger tri_emp enable;
--删除触发器
drop trigger tri_emp
--不能增删改
create or replace trigger tri_emp1
before update or delete or insert on emp
begin
if to_char(sysdate,'day') in ('星期日') then
if updating then
raise_application_error(-20001,'星期日不能修改enp表');
elsif deleting then
raise_application_error(-20001,'星期日不能删除enp表');
else
raise_application_error(-20001,'星期日不能添加enp表');
end if;
end if;
end;
delete from emp where empno=7499;
--失效触发器
alter trigger tri_emp1 disable;
--行级触发器
--部门为30的人工资,奖金不能降低,而且不能删除
create or replace trigger tri_emp2
before update or delete on emp
--for each row 相当于声明:new,:old ,没有for each orw 则不能使用
for each row when(old.deptno=30)
begin
if updating('sal') then
if :new.sal<:old.sal then
raise_application_error(-20000,'工资不能降低');
end if;
elsif updating('comm') then
if :new.comm<:old.comm then
raise_application_error(-20000,'奖金不能降低');
end if;
elsif deleting then
raise_application_error(-20000,'不能删除');
end if;
end;
update emp set sal=15000 where deptno=30;
select *from emp
delete from emp
--失效触发器
alter trigger tri_emp2 disable;
--after语句触发器(常用于,级联添加,级联删除)
--在修改dept表中deptno后,顺便把它级联人员表中部门编号更新
create or replace trigger tri_emp3
after update on dept
for each row
begin
update emp set deptno=:new.deptno where deptno=:old.deptno;
end;
update dept set deptno=60 where deptno=20
select * from dept
select * from emp
--失效触发器
alter trigger tri_emp3 disable;
--触发器调用存储过程
--删除dept表中记录,将原有的记录保存到一个回收表delDept表中
create table delDept(
deptno number(10),
dname varchar(200),
loc varchar(200)
)
create or replace procedure insertDelDept(v_deptno number,v_dname varchar2,v_loc varchar2)
is
begin
insert into deldept(deptno,dname,loc) values(v_deptno,v_dname,v_loc);
end;
create or replace trigger tri_delDept
after delete on dept
for each row
begin
--insert into deldept values(:old.deptno,:old.dname,:old.loc);
insertDelDept(:old.deptno,:old.dname,:old.loc);
end;
select * from dept
delete from dept where deptno=44
select * from delDept
--系统触发器
create table loginlog(
loguser varchar2(200),
loginip varchar(200),
logindate date
)
select *from loginlog
create or replace trigger logintest_tri
after logon database
begin
insert into loginlog values(ora_login_user,ora_client_ip_address,sysdate);
end;
Oracle游标和触发器
最新推荐文章于 2022-04-25 11:56:36 发布