oracle 学习笔记

/*
  游标 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 数据库中,有不同的方案,可以在一个具体的方案中,创建同义词来引用另外一个表中的数据,象是自己的表一样。

常用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' 



你可能感兴趣的:(oracle 学习笔记)