/* 游标 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;
oracle 序列 和同义词
/* 序列 sequence : 序列号,在每次取的时候自动增加(第一次使用是初始值) start with number : 从多少开始增长 increment by number : 每次增长多大 nomaxvalue : 没有最大值,不限制最在值 nocycle : 不循环 cache number : 预先在内存里存放一些sequence , 这样存取速度快. nocache: 数据库突然不正常down掉(shutdown abort),cache中的sequence就会丢失。 所以可以在create sequence的时候用nocache防止这种情况 使用序场所: 1. insert语句 values 2. update语句 set */ --创建序列 /*需要有 create sequence 或 create any sequence权限*/ create sequence seq_up1 start with 1 increment by 1 nomaxvalue nocycle cache 10; create sequence seq_up2 start with 10 increment by 2 maxvalue 100 cycle nocache; --使用序列 select seq_up1.nextval from dual ; --让序列增长,并返回下一个值 select seq_up1.currval from dual ; --返回序列当前值 select seq_up2.nextval from dual ; select seq_up2.currval from dual ; insert into t10(id,name,address) values(seq_up2.nextval,'张二','不详'); --修改序列 alter sequence seq_up2 increment by 1 maxvalue 1000 ; --删除序列 drop sequence seq_up2 ; /* 同义词 synonyms 优点:节省大量的数据库空间,对不同用户的操作同一张表没有多少差别; 扩展的数据库的使用范围,能够在不同的数据库用户之间实现无缝交互; 同义词可以创建在不同一个数据库服务器上,通过网络实现连接。 */ --创建同义词 conn sys/change_on_install ; --以sys/change_on_install身份登录进去 select * from emp ; --查看emp提示无此表或视图 select * from scott.emp ; --可以查询,可知emp表是属于scott的 create synonym emp for scott.emp ; --创建同义词emp,它的作用是scott.emp的别名 select * from emp ; --利用创建的同义词(表的别名)来查询,ok --查看所有同义词 select * from user_synonyms ; --删除同义词 drop synonym emp ; --创建公共同义词 create public synonym dept for scott.dept; --删除公共同义词 drop public synonym dept ;
常用ORACLE 语句
drop TABLE FBI_BAI_TRANS_HIS; commit; --删除 表结构 select * from all_users; -- 查询当前系统下所有的用户 select count(*) from dba_tables t where t.owner='TEST'; -- 查看当前用户下表的个数
oracle 删除用户下所有的表,以下SQL 会生成删除所有表的SQL.
select 'drop table '||table_name||';' from cat where table_type='TABLE'