您的位置:首页 > 数据库 > Oracle

oracle 学习笔记

2012-04-10 09:07 344 查看
/*
游标 cursor
*/
declare
cursor c is   --声明游标时并不从数据库查询数据
select * from emp ;
v_emp c%rowtype;
begin
open c;  --open游标才真正的查询数据保存到内存
loop
fetch c into v_emp;
exit when (c%notfound);
dbms_output.put_line(v_emp.ename);
end loop;
close c;  --关闭游标
end;
/

declare
cursor c is
select * from emp ;
v_emp c%rowtype;
begin
open c;
fetch c into v_emp;
while(c%found) loop
dbms_output.put_line(v_emp.ename);
fetch c into v_emp ;
end loop;
close c;
end;
/

declare
cursor c is
select * from emp ;
begin
for v_emp in c loop
dbms_output.put_line(v_emp.ename);
end loop;
end;
/

--带参数游标
declare
cursor c(v_deptno emp.deptno%type,v_job emp.job%type) is
select ename,sal from emp where deptno=v_deptno and job=v_job;
--v_temp c%rowtype;
begin
for v_temp in c(30,'CLERK') loop
dbms_output.put_line(v_temp.ename);
end loop;
end;
/
--可更新游标
declare
cursor c is
select * from emp2 for update;
begin
for v_temp in c loop
if(v_temp.sal<2000) then
update emp2 set sal=sal*2 where current of c ;
elsif(v_temp.sal=5000) then
delete from emp2 where current of c;
end if;
end loop;
commit;
end;
/
/*
存储过程 Procedure
创建存储过程必须有create procedure权限
*/

--打开显示
set serveroutput on;
--创建一个存储过程
create or replace procedure p_update_emp
as
cursor c is
select * from emp for update;
begin
for v_emp in c loop
if(v_emp.deptno = 10) then
update emp set sal=sal+10 where current of c;
elsif(v_emp.deptno = 20) then
update emp set sal=sal+20 where current of c;
else
update emp set sal=sal+50 where current of c;
end if ;
end loop;
commit;
end;
/

--查询所有存储过程
/*
这里比较好玩:根据一般数据字典表中的列命名,这里p_update应为procedure_name
但是不是,它是object_name,procedure_name为空
*/
select * from user_procedures;

--执行存储过程 (方式一)
begin
p_update_emp;
end;
--执行存储过程 (方式二)
exec p_update_emp;

--创建带参数存储过程
/*
in : 表输入参数
out: 表输出参数
不加关键字的表示默认输入参数
两个都加的既表示输入参数又表示输出参数

注意:存储过程的参数只能指定类型,而不能指定大小
如  v_a number(2)是错误的,正确为v_a number
*/
create or replace procedure p_in_out
(v_a in number,v_b number,v_ret out number,v_temp in out number)
as
begin
if(v_a > v_b) then
v_ret := v_a ;
else
v_ret := v_b ;
end if ;
v_temp := v_temp +1 ;
end;
/

--执行带参存储过程
declare
v_a number := 3 ;
v_b number := 4 ;
v_ret number;
v_temp number := 5 ;
begin
p_in_out(v_a,v_b,v_ret,v_temp);
dbms_output.put_line(v_ret);
dbms_output.put_line(v_temp);
end;
/
--结果打印 4 和 6

--删除存储过程
drop procedure p_update_emp;

declare
v_a number :=1;
v_b number :=2;
v_set number:=3;
v_temp number :=4;
begin
p_in_out(v_a,v_b,v_set,v_temp);
dbms_output.put_line(v_set);
dbms_output.put_line(v_temp);
end;
/
/*
触发器 trigger
触发器必须依附于表才能起作用
*/

--创建日志表 emp_log,用于记录对表emp的所有操作日志
create table emp_log
(
uname varchar2(20),
action varchar2(10),
atime date
);

--创建触发器
/*
触发条件:insert|delete|update 对某张表做插入|删除|更新的操作
触发时间:after|before 操作之后|操作之前
触发行:each row 操作影响一行触发一次,不写表求一次操作触发一次
*/
create or replace trigger trig
after insert or delete or update on emp for each row
begin
if inserting then
insert into emp_log(uname,action,atime) values(USER,'insert',sysdate);
elsif updating then
insert into emp_log(uname,action,atime) values(USER,'update',sysdate);
elsif deleting then
insert into emp_log(uname,action,atime) values(USER,'delete',sysdate);
end if ;
end;
/

--触发
update emp set sal=sal*2 where deptno=30;
delete from emp where empno = 7369 ;

--查看日志表
select * from emp_log;

--? : 有外键关系时,主表中的主键存在外表的引用关系,因此不能随意更新,但可以用触发器解决这个问题
--如: update dept set deptno=99 where deptno=10

--删除触发器
drop trigger trig;

create or replace trigger trig
after update on dept for each row
begin
update emp set deptno = :NEW.deptno where deptno = :OLD.deptno ;
end;
/
/*
通常一条update语句会产生新旧两个状态 :NEW代表新状态 :OLD代表旧状态
*/
update dept set deptno=99 where deptno=10;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: