Oracle笔记全解

第一部分:管理

一、安装oracle

二、卸载
	1、停止oracle所有的服务
	2、运行oracle Universal Installer卸载oracle
	3、修改注册表,删除所有关于oracle的信息
		开始-运行-regedit
		HKEY_LOCAL_MACHINE\SOFTWARE\ORACLE
		HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Oracle开头的内容删除
		HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Application\Oracle开头的内容删除
	4、删除oracle系统目录C:\Program Files\Oracle
	5、删除各种快捷方式(开始菜单,环境变量)
	6 、(重启系统)删除oraclede的工作目录

三、软件版本
	8i(Internet)
	9i
	10g(Grid)
	11g

四、
	Oracle------甲骨文
	DB2---------IBM

	MySQL-------SUN(甲骨文)---开源
	SQL Server--Microsoft

	Oracle:神谕
	sqlplus
	启动sqlplus
	
	1、通过命令行
		cmd-sqlplus-username-password
		system/orcl

	2、通过集成工具

	3、通过浏览器
		启动iSQLPlus的服务
		地址:http://计算机名:5560/isqlplus

	访问问题:

		sql server
		mysql		

		oracle

		只有一个全局数据库

		所有的表都在同一个数据库中

		用户隔离

		主机字符串

		实例:一组内存和进程

		一个实例对应着一个数据库

		数据库:由一组数据文件,日志文件,控制文件

	使用对象:
		
		DBA(数据库管理员,经验)
		数据库的安装,配置
		用户的创建
		权限的分配

		数据库的备份,恢复
		数据库参数的调整和数据库的优化
		对数据库使用的总体规划

		程序员(应用角度)
		表
		视图
		触发器
		存储过程
		函数
		序列
		同义词
		SQL语句
	

五、SQL PLUS的使用
	1、命令使用分号结尾

	2、edit;编辑缓存区中存放的SQL命令

	3、 show user;
	    select * from tab;
	    desc emp;
	    help index;
	    help conn;
	4、保存缓冲区中的命令:
		save c:/a.sql
		@ c:/a.sql	
	5、set
		set linesize 100
		set pagesize 100
		set wrap off;关闭自动回行
		break on job;
	6、备份SQL PLUS命令:
		spool c:/a.txt;
		select * from emp;
		spool off;

六、安全管理

	创建用户
		(必须使用sys/system这两个用户创建其他用户)
	create user user1 identified by aaa;
	drop user user1;

	权限
	授权:	
	grant connect,resource to user1;

	表级别权限:
	grant all on scott.dept to user1;

	角色:(权限的集合)
	create role user_role;
	grant connect,resource to user_role;
	create user user2 identified by aaa;
	grant user_role to user2;

七、表空间
	虚拟的概念,逻辑概念

	user1-------表空间中------数据文件
	创建:
	create tablespace myts_test datafile 'C:\first.dbf' size 10M

	my_user
	 create user my_user identified by aaa default tablespace myts_test;

八、表的管理
	1、数据类型
		数字型:number(p,s);
		字符型:char,varchar2
		日期型:date('10-9月-2010')
		大对象类型:clob(文本文件)
			    blob(4G)

	2、创建表

		create table my_tab(
		   id number(5),
		   name varchar2(10),
		   birth date
		);
	3、表的约束
		主键:primary key
		外键:foreign key
		非空:not null
		唯一:unique
		检查:check

		student
		id(主键)
		name(不能为空)
		sex(只能男,女)
		birth(不能为空)
		mark
		gid
		
		grade
		id(主键)
		name(不能为空)
		loc(不能重复)
	4、修改表
		添加新列:alter table student add age number(3);
		删除  列: alter table student drop (age);
		修改列数据类型:alter table student modify age number(3);

		删除表:
			delete from ttt ;(删除的是表中的数据,速度慢,数据可以恢复)
			truncate table ttt;(删除表中的数据,速度快,数据不可以恢复)
			drop table ttt;(删除表结构)

	5、表的导入与出
		转储文件(dump file)
		导出:exp(c:\a.dmp)
		导入:imp



第二部分 开发

	SQL

	结构化查询语言(Structured Query Language)IBM,ANSI,ISO指定了一个标准SQL-92

	DDL(数据定义语言Data Definition Language) create drop alter
	DML(数据操作语言Data Manipulation Language)insert,update,delete
	DQL(数据查询语言Data Query Language)select
	DCL(数据控制语言Data Control language)grant revoke commit rollback

	DML(CRUD)

	查询
	a:基本查询

		select * from emp;
		select ename,deptno from emp;
		select ename,deptno from emp e;
		select ename as "职员姓名",deptno as "部门编号" from emp;

	b:条件查询
		select * from emp where sal>1500;
		oracle中运算符
		等值:=,>,>=,<,<=,!=(<>)
			select * from emp where sal<>1600;
		包含:in ,not in
			select * from emp where job in('CLERK');
		范围:between...and,not between...and
			select * from emp where sal between 1500 and 2000;
		null:select * from emp where comm is not null;

		布尔连接:and,or,not
			select * from emp where sal>1000 and comm is not null;
			select * from emp where sal>1000 or comm is not null;

		匹配测试:like,not like
			通配符
			%:表示任意数量的字符,包含没有
			_:确切数量的任意字符
			select * from emp where ename like '%A%';
			select * from emp where ename like '__A%';

	c:排序查询
		order by,asc,desc
			select * from emp order by deptno asc,sal desc;
	
	d:分组查询
		group by
		聚合函数(max,min,sum,avg,count)
				
		select avg(sal) from emp group by deptno;
		select count(ename) from emp group by deptno;
		select sum(sal) from emp group by deptno;
		
		having
		select avg(sal) as "平均工资",deptno as abc from emp group by deptno having avg(sal)>2000;

		每个部门的每种岗位的平均和最低工资
		select avg(sal),min(sal) from emp group by deptno,job;

		每个部门的每种岗位的平均和最低工资,部门号,
		岗位,平均工资大于2000的数据,按照部门号升序显示数据

		select avg(sal),min(sal),deptno,job 
		from emp  group by deptno,job having avg(sal)>2000 order by deptno asc;

		注意:分组,筛选,排序一起使用的时候,先后顺序:group by,having,order by

	e:多表查询

		迪尔卡集现象
		所有员工信息(姓名,工资,部门名字,部门地址)
		
		n-1
		
		联合查询:
		内联:(等值查询)

			select ename,sal,dname,loc from emp,dept where emp.deptno=dept.deptno;
			select ename,sal,dname,log from emp inner join dept on emp.deptno=dept.deptno;
			select ename,sal,dname,log from emp join dept on emp.deptno=dept.deptno;
			结果一定是都满足条件的数据

		外联:
			左联左不丢,右联右不丢
			
			左外联接:左表中满足条件不满足条件的数据,右表中满足条件的数据,右表中不满足条件的用null占位
				select ename,dname from emp left join dept on emp.deptno=dept.deptno;
				select ename,dname from emp left outer join dept on emp.deptno=dept.deptno;
				select ename,dname from emp,dept where emp.deptno=dept.deptno(+);

			右外联接:右表中满足条件不满足条件的数据,左表中满足条件的数据,左表中不满足条件的用null占位
				在职员工姓名,员工所在的部门名,没有员工的部门名
				select ename,dname from emp right join dept on emp.deptno = dept.deptno; 
				select ename,dname from emp right outer join dept on emp.deptno = dept.deptno;
				select ename,dname from emp,dept where emp.deptno(+)=dept.deptno;
			全外联接:所有数据
				select ename,dname from emp full  join dept on emp.deptno = dept.deptno;
				select ename,dname from emp full outer join dept on emp.deptno = dept.deptno;

		联合查询综合练习:
				create table student( --学生表
				studentid number(3) primary key, --学生编号
				studentname varchar2(20) --学生的姓名
				); 
				create table subject( --课程表
				subjectid char(3) primary key, --课程编号
				subjectname varchar2(20)  --课程的名字
				);
				create table grade( --分数表
				studentid number(3) references student(studentid), --学生id
				subjectid char(3) references subject(subjectid), --课程id
				mark      number(3), --分数
				primary key (studentid,subjectid) --联合主键
				);

				insert into student values (101,'张三');
				insert into student values (102,'李云');
				insert into student values (103,'张丹');

				insert into subject values ('A01','C++');
				insert into subject values ('A02','ASP');
				insert into subject values ('A03','JAVA');


				insert into grade values (101,'A01',59);
				insert into grade values (101,'A02',72);
				insert into grade values (101,'A03',90);

				insert into grade values (102,'A01',75);
				insert into grade values (102,'A02',91);

				insert into grade values (103,'A01',71);
			作如下4题

				第一问:查询出以下信息
					学号 学生姓名 课程名称 成绩 (要全部学生信息)
				       select a.studentid as "学号",
				       studentname as "学生姓名",
				       subjectname as "课程名称",
				       mark        as "成绩"
				       from student a, subject b, grade c
				       where a.studentid = c.studentid
				       and b.subjectid = c.subjectid;				
				
				第二问:查询出以下信息
					学号 学生姓名 课程名称 成绩(只显示每科最高分)

				       select a.studentid as "学号",
				       studentname as "学生姓名",
				       subjectname as "课程名称",
				       mark        as "成绩"
				       from student a, subject b, grade c
				       where a.studentid = c.studentid
				       and b.subjectid = c.subjectid
				       and(
				       select count(*) from grade
				       where subjectid=b.subjectid
				       and mark >c.mark               
				       )=0

				第三问:查询出以下信息
					学号 学生姓名 课程名称 成绩 (成绩大于60时的显示及格,小于60时的显示不及格)

				       select a.studentid as "学号",
				       studentname as "学生姓名",
				       subjectname as "课程名称",
				       decode(sign(mark-60),-1,'不及格','及格') as "成绩"
				       from student a, subject b, grade c
				       where a.studentid = c.studentid
				       and b.subjectid = c.subjectid

				第四问:查询出以下信息
					学号 学生姓名 (查询出课程超过1门以上学生的信息)

				       select a.studentid as "学号",
				       studentname as "学生姓名"
				       from student a, subject b, grade c
				       where a.studentid = c.studentid
				       and b.subjectid = c.subjectid
				       group by studentname
				       ,a.studentid
				       having count(studentname)>1
			HR用户中示例表的练习:

			1、查询所有雇员的last_name,department_name,country_id
				select last_name,department_name,c.country_id
				from employees a,departments b,locations c
				where a.department_id=b.department_id 
				and b.location_id = c.location_id;
			
			2、部门是80的所有工作岗位,并输出部门的地点
				select job_id,location_id 
				from employees e,departments d 
				where e.department_id = d.department_id
				and e.department_id=80;

		f:子查询				
			
			工资大于部门号30的平均工资员工信息
			select * from emp where sal>(select avg(sal) from emp where deptno=30);
			工资大于部门号30的最低工资员工信息
			select * from emp where sal>(select min(sal) from emp where deptno=30);
			工资大于部门号30的最高工资员工信息
			select * from emp where sal>(select max(sal) from emp where deptno=30);
			工资大于部门30的所有员工的工资的员工信息
			all
			select * from emp where sal>all(select sal from emp where deptno=30);
			工资大于部门30的任意一个员工的工资的员工信息
			any
			select * from emp where sal>any(select sal from emp where deptno=30);
			查询有员工的部门
			in
			select * from dept where deptno in(select distinct deptno from emp);
			
			查询'KING'的同部门同事的信息,结果中不能包含‘KING’
			select * from emp where deptno =
			(select deptno from emp where ename='KING') and ename<>'KING';

			查询'KING'的部下的信息
			select * from emp where mgr=(select empno from emp where ename='KING');

			查询与'ALLEN'相同部门的员工信息
			select * from emp where deptno=(select deptno from emp where ename='ALLEN');
			自联:
			select e2.ename,e2.deptno,e2.sal 
			from emp e1,emp e2 
			where e1.deptno = e2.deptno 
			and e1.ename='ALLEN';
			员工姓名,上级姓名
			自联:
			select e1.ename as "员工",e2.ename as "上级" from emp e1 ,emp e2 where e2.empno=e1.mgr

		单行函数
			
			1、distinct去掉重复数据
				显示emp表中的职位
				select distinct job from emp;
			2、||连接符
				按照如下格式显示数据:The Employee SMITH job is ClERK
				select 'The Employee '||ename|| ' job is '||job as "员工的职位" from emp;
			3、字符函数:
			   lower(),upper(),转换大小写
				select upper(ename),lower(job) from emp;
			   concat(),length(),substr(str,2,2);
			   instr('abcde','a')---返回字符a的索引值是1

			   select concat(first_name,last_name) as "姓名",
			   length(last_name) as "名字长度" 
			   from employees 
			   where substr(last_name,2,1)='a';
			4、数字函数
			   round()四舍五入
			   trunc()截取数字
			   mod()求余数
			5、日期函数
			   sysdate,系统时间
			   next_day(sysdate,'星期五'),
			   next_day(sysdate,6),
			   当前时间下个星期五的日期
			   last_day();
				
			   显示McCain的入职周数
				   select round((sysdate-HIRE_DATE)/7 )as "入职周数" 
				   from employees 
				   where 
				   last_name='McCain';
				  
		          98年入职的员工的入职月份
				  select last_name,hire_date,trunc(hire_date,'MONTH') 
				  from employees 
				  where hire_date 
				  like '%98';
			6、to_char:转换函数
				日期---字符
				select to_char(sysdate,'fm yyyy Month DD') from dual;
				select to_char(sysdate,'fm yyyy "年" Month DD "号"') from dual;
				select to_char(sysdate,'fm yyyy "/" Month "/" DD') from dual;
				select to_char(sysdate,'fm yyyy "-" Month "-" DD') from dual;
				select ename,job,sal,to_char(hiredate,'fm yyyy"年"') from emp;
				数字---字符
				select ename,job,to_char(sal,'L99,999999,.99'),to_char(hiredate,'fm yyyy"年"') from emp;
				select ename,job,to_char(sal,'$99,999,999.99'),to_char(hiredate,'fm yyyy"年"') from emp;
				L:本地货币符号
				$:美元符号
				9:表示一位数
	操作数据

		插入:

			create table emp_copy as select * from emp;
			insert into emp_copy values(1000,'aaaa','CLERK',7839,'12-12月-2009',2000,200,10);
			insert into emp_copy(empno,ename) values(1000,'aaaa');
			insert into emp_copy select * from emp_copy;

		修改:
			update
			update emp_copy set empno=rownum;
			update emp_copy set sal=10000 wehre empno=200000;

		删除:  delete from emp_copy;
			delete from emp_copy where empno=100;
			delete from emp_copy where empno=(select empno from emp where ename='KING');

第三部分	 数据库的其他对象

	user,role,table

	1、序列(sequence)
		一组不重复的数字组成,用来产生唯一数字列值的数据库对象
		create sequence my_seq1;
		nextval
		currval
		
		升序序列
		create sequence my_seq2
		increment by 10--每次增长10
		start with 10000--起始值
		maxvalue 200000--最大值
		cycle--自动循环
		cache 20--放入缓存中序列值个数
		降序序列
		create sequence my_seq4
		increment by -10
		start with 200000
		maxvalue 200000
		minvalue 10000
		cycle
		cache 20(nocache)

	2、视图(view)
		简单视图(单基表视图)
		是一个命名的查询,虚拟的表,表的透视图,视图并不存储数据
		create view emp_view as select * from emp;
		使用视图(CRUD)
		复杂视图(多基表视图)
		create view emp_dept 
		as 
		select ename,sal,dname,loc 
		from emp e,dept d 
		where e.deptno=d.deptno;
		使用视图(CRUD)
		不可以通过多基表视图进行修改数据

	3、索引(index)

		create index emp_ename_index on emp(ename);

		create table emp_copy as select * from emp;--拷贝emp表

		insert into emp_copy select * from emp_copy;--反复执行

		alter table emp_copy modify empno number(8);--修改字段类型

		update emp_copy set empno=rownum;--修改表中empno数据为行号,使值唯一

		set timing on;--打开显示操作时间

		select * from emp_copy where empno=500000;--创建索引之前使用时间

		create index emp_copy_empno_index on emp_copy(empno);--创建索引

		select * from emp_copy where empno=500000;--创建索引之后使用时间

		drop index a;--删除索引

	4、同义词(synonym)
		scott.emp-----se
		create synonym se for emp;
		create synonym ed for emp_dept;(private)
		private 
		public(必须是sys,system的身份才可以创建公用的同义词);
		create public synonym ed2 for scott.emp_dept;????????

	user,role,table,sequence,index,view,synonym


第四部分、PL/SQL

	Procedual Language/Structured Query Language
	
	语句块(匿名块)---存储过程,函数,触发器,包

	语句块
	工具:pl/sql developer,sqlplus
	declare(可选)
	--定义变量
	begin
	--执行的部门
	exception(可选)
	--处理异常
	end;
	--结束语句块
	set serverout on--打开服务器的输出
	第一个程序案例HelloWorld!!!
		begin
		dbms_output.put_line('HelloWorld!!!');
		end;
	定义变量,使用变量
		declare
		  v_name varchar2(8);
		  v_age number(3);
		  v_sex boolean;
		  v_email string(20);
		  v_score integer;
		begin
		  v_name:='张三';
		  v_age:=20;
		  v_sex:=true;
		  v_email:='aaa@126.com';
		  v_score:=80;
		  dbms_output.put_line(v_name||' '||v_age||' '||v_score||' '||v_email);
		end;
	注释:--单行注释、/*...*/多行注释
	分支结构
		--if结构 
		    declare
		      v_num number;
		      v_str varchar2(4);
		    begin
		      v_num:=2;
		      if v_num=1 then
		      v_str:='A';
		      elsif v_num=2 then
		      v_str:='B';
		      else
		      v_str:='C';
		      end if;
		      dbms_output.put_line(v_str);
		    end;
		--case结构 
		    declare
		      v_num number;
		      v_str varchar2(10);
		    begin
		      v_num:=2;
		      case
			when v_num=1 then v_str:='A';
			when v_num=2 then v_str:='B';
			when v_num=3 then v_str:='C';
			else
			v_str:='other';
		      end case;
		      dbms_output.put_line(v_str);
		    end;
		--循环
		--loop循环 1(使用 if 判断,跳出循环  )
		    declare
		      v_x number;
		    begin
		      v_x:=1;
		      loop
			v_x:=v_x+1;
			if v_x=10 then
			exit;
			end if;
			dbms_output.put_line('循环体内v_x的值是:'||v_x);
		      end loop;
		      dbms_output.put_line('循环体外v_x的值是:'||v_x);
		    end;
		--loop循环2(使用 when 判断,跳出循环)
		    declare
		      v_x number;
		    begin
		      v_x:=1;
		      loop--循环开始 
			v_x:=v_x+1;
			exit when v_x=10;--使用 when    
			dbms_output.put_line('循环体内v_x的值是:'||v_x);
		      end loop;--循环结束 
		      dbms_output.put_line('循环体外v_x的值是:'||v_x);
		    end;
		--while循环
		    declare
		      v_x number;
		    begin
		      v_x:=1;
		      while v_x<=10 loop
			v_x:=v_x+1;
			dbms_output.put_line('循环体内v_x的值是:'||v_x);
		      end loop;
		      dbms_output.put_line('循环体外v_x的值是:'||v_x);
		    end;
		--for 1循环 从小到大 
		    declare
		      v_x number;
		    begin
		      v_x:=10;
		      for i in 1..v_x loop
			dbms_output.put_line('循环体内i的值是:'||i);
		      end loop;
		    end;
		--for 2循环 从大到小 
		    declare
		      v_x number;
		    begin
		      v_x:=10;
		      for i in reverse 1..v_x loop--reverse 反向 循环 
			dbms_output.put_line('循环体内i的值是:'||i);
		      end loop;
		    end;

	实用练习:
	1、pl/sql与sql结合
		DML(CRUD),不能写DDL,DCL 
		     declare
		       v_ename varchar2(20);
		     begin
		       select ename into v_ename from emp where empno=&no;
		       dbms_output.put_line(v_ename);
		     end; 
		   --&工具接受用户键盘的输入 
		   --查询多个字段数据放入变量需要一 一对应
		     declare
		       v_ename varchar2(20);
		       v_sal number(10,2);
		     begin
		       select ename,sal into v_ename,v_sal from emp where empno=&no;
		       dbms_output.put_line(v_ename||' '||v_sal);
		     end; 
		   --基本类型的变量只能放一条数据 
		     declare
		       v_ename varchar2(20);
		       v_sal number(10,2);
		     begin
		       select ename,sal into v_ename,v_sal from emp;--会出现异常 
		       dbms_output.put_line(v_ename||' '||v_sal);
		     end;
		   --变量的类型可以指定为表中字段的类型 使用  表名.字段名%type
		     declare
		       v_ename emp.ename%type;
		       v_sal emp.sal%type;
		     begin
		       select ename,sal into v_ename,v_sal from emp where empno=&no;
		       dbms_output.put_line(v_ename||' '||v_sal);
		     end; 
		   --变量的类型还可以是一整条数据的类型  使用行类型作为变量类型 表名%rowtype
		     declare
		       v_data emp%rowtype;       
		     begin
		       select * into v_data from emp where empno=&no;
		       dbms_output.put_line(v_data.ename||' '||v_data.sal||' '||v_data.deptno);
		     end; 
		   --打印dept表中的数据
		     declare
		     v_dept_data dept%rowtype;--复合类型
		     v_dept_count number(4);
		     begin
			select count(*) into v_dept_count from dept;		     
		     for i in 1..v_dept_count loop
		     select * into v_dept_data from
		     (select * from dept where rownum<=i minus select * from dept where rownum<=i-1);	
		     dbms_output.put_line(v_dept_data.deptno||','||v_dept_data.dname||','||v_dept_data.loc);
		     end loop;		     
		     end;


	异常:
		系统异常:
		no_data_found没找到数据
		too_many_rows返回多行
		zero_divede分母为0
		dup_val_on_index唯一字段中插入相同的值.....
		invalid_number输入数据有误出现的异常
		value_error赋值操作异常
			declare
			v_ename emp.ename%type;
			begin
			select ename into v_ename from emp where empno=&no;
			dbms_output.put_line(v_ename);
			exception
			when no_data_found then
			null;
			dbms_output.put_line('是否执行');
			end;
		自定义异常
			declare
			v_ename emp.ename%type;
			v_my_exception exception;--自定义异常 
			begin      
			select ename into v_ename from emp where empno=&no;
			if v_ename<>'SCOTT' then
			raise v_my_exception;--抛 出异常 
			end if;
			dbms_output.put_line(v_ename);      
			exception
			when v_my_exception then--处理自定义异常 
			dbms_output.put_line('不是SCOTT');
			when no_data_found then
			dbms_output.put_line('无此员工');
			when others then--处理其他异常 
			null;--不做接下来的任何操作 
			dbms_output.put_line('是否执行');
			end;

	命名块---语句块(名字)
	可重用性
	安全性
	抽象,隐藏底层数据信息
	不能移植(oracle---db2)
	oracle------pl/sql
	sql/server----T-SQL
	db2-------sqlpl
     存储过程(procedure)
	create or replace procedure first_pro
	is--is/as定义部分	
	begin
	dbms_output.put_line('Hello Procedure');	
	end;
	调用
	1、通过命令调用
	exec first_pro;
	2、程序调用(pl/sql,java程序)
	pl/sql语句块调用
	begin
///	first_pro;
	end;
	/ 

	具有插入功能的存储过程 
		create or replace procedure insert_dept
		is
		begin
		insert into dept values(11,'English','上海');
		end; 
	存储过程中的参数 (输入参数 )
		create or replace procedure insert_dept(
		v_deptno in dept.deptno%type,
		v_dname dept.dname%type,
		v_loc dept.loc%type
		)
		is
		begin
		insert into dept values(v_deptno,v_dname,v_loc);
		end;
	删除功能的存储过程 
		create or replace procedure delete_dept(
		v_deptno dept.deptno%type
		)
		is
		begin
		delete from dept where deptno=v_deptno;
		end;
	修改功能的存储过程 
		create or replace procedure update_dept(
		v_deptno dept.deptno%type,
		v_dname dept.dname%type,
		v_loc dept.loc%type
		)
		is
		begin
		update dept set dname=v_dname,loc=v_loc where deptno=v_deptno;
		end;
	查询的存储过程 ,输出参数 
		create or replace procedure find_emp(
		v_empno emp.empno%type,
		v_ename out emp.ename%type
		)
		is
		begin
		select ename into v_ename from emp where empno=v_empno;
		end;
	调用带有输出参数的存储过程 
	必须在语句块里调用 ,不能通过exec命令调用 
		declare
		v_name emp.ename%type;
		begin
		find_emp(7788,v_name);
		dbms_output.put_line(v_name);
		end;
	创建查询部门信息的存储过程 
		create or replace procedure find_dept(
		v_deptno dept.deptno%type,
		v_dname out dept.dname%type,
		v_loc out dept.loc%type
		)
		is
		begin
		select dname,loc into v_dname,v_loc from dept where deptno=v_deptno;
		end;

	java-----调用存储过程
	1、java连oracle(url,drivername,username,password),scott/aaa
		项目中导入ojdbc14.jar文件
		url:jdbc:oracle:thin:@localhost:1521:orcl
		drivername:oracle.jdbc.OracleDriver
	2、发送调用存储过程的语句,使用CallableStatement
		CallableStatement cstmt = null;
		cstmt = conn.prepareCall("{call find_dept(?,?,?)}");
		cstmt.setInt(1, deptno);
		//注册输出参数类型
		cstmt.registerOutParameter(2, oracle.jdbc.OracleTypes.VARCHAR);
		cstmt.registerOutParameter(3, oracle.jdbc.OracleTypes.VARCHAR);		
		//先执行存储过程
		cstmt.execute();
		//得到具体的数据 
		String dname = cstmt.getString(2);
		String loc = cstmt.getString(3);	
	--参数既是输入参数也是输出参数 
		create or replace procedure avg_sal_dept(v_n in out number)
		is
		begin
		select avg(sal) into v_n from emp where deptno=v_n;
		end;
		--调用 该存储过程 
		declare
		v_d number(10);
		begin
		v_d:=10;
		avg_sal_dept(v_d);
		dbms_output.put_line(v_d);
		end;
	
      函数(function):
		计算员工的年收入:12*sal+12*nvl(comm,0)

	      --创建函数 
		create or replace function empl_income(v_no emp.empno%type)
		return number
		is
		v_income number(8,2);
		begin
		select (sal*12+nvl(comm,0)*12) into v_income from emp where empno=v_no;
		return v_income;
		end;
		--调用函数 
		--作为sql的字句来调用 
		select empl_income(7788) from dual;
		--函数 主要用于计算 ,头部必须有 return语句, 必须要有返回值

	程序包(package)
		create package mypackage01 is
		procedure find_dept(
			v_deptno dept.deptno%type,
			v_dname out dept.dname%type,
			v_loc out dept.loc%type
			);
		function empl_income(v_no emp.empno%type)return number;
		end;
	pl/sql中的包内容(过程或函数),只能声明,不实现
	创建包体(在包体中实现包中没有实现的过程或函数)
		create package body mypackage01 is
		procedure find_dept(
			v_deptno dept.deptno%type,
			v_dname out dept.dname%type,
			v_loc out dept.loc%type
			)
		is
		begin
		select dname,loc into v_dname,v_loc from dept where deptno=v_deptno;
		end;
		function empl_income(v_no emp.empno%type)return number
		is
		v_income number(8,2);
		begin
		select (sal*12+nvl(comm,0)*12) into v_income from emp where empno=v_no;
		return v_income;
		end;
		end;
	在包中可以定义变量,类型,过程,函数,游标
	变量:
		定义:变量名 类型
		标量类型:varchar2,number,date.......
		复合类型:%type,%rowtype,record(记录类型),table(表格类型)
			
			record:
			创建程序包,在包中定义类型
			create package mypackage02 is
			type v_record is record(v_ename emp.ename%type,v_sal emp.sal%type,v_hiredate emp.hiredate%type);		
			end;
			--语句块中使用记录类型
			declare
			--type v_record is record(v_ename emp.ename%type,v_sal emp.sal%type,v_hiredate emp.hiredate%type);
			--使用包中的类型
			v_data mypackage02.v_record;
			begin
			select ename,sal,hiredate into v_data from emp where empno=&no;
			dbms_output.put_line(v_data.v_ename||','||v_data.v_sal||','||v_data.v_hiredate);
			end;			
		
		参照类型:游标
	游标:(cursor)
		游标是一种pl/sql中的控制结构,可以对sql语句的处理进行显示控制,便于对表数据进行逐条处理,
		可以显示遍历结果集,可以通过游标向外部应用程序传递一个结果集
	    处理游标流程
	     (1)声明游标
	         cursor cur_name is selelct......
	     (2)打开游标
		 open cur_name;
	     (3)从游标中抓取数据
	         fetch cur_name into v_data....
	     (4)关闭游标
		 close cur_name
	--使用游标案例
		declare
		cursor my_cur is select * from emp;
		v_data emp%rowtype;
		begin
		open my_cur;
		fetch my_cur into v_data;
		dbms_output.put_line(v_data.ename||','||v_data.sal);
		fetch my_cur into v_data;
		dbms_output.put_line(v_data.ename||','||v_data.sal);
		close my_cur;
		end;
	--使用loop循环处理 
		declare
		cursor my_cur is select * from emp;
		v_data emp%rowtype;
		begin
		open my_cur;
		loop  
		fetch my_cur into v_data;
		exit when my_cur%notfound;
		dbms_output.put_line(v_data.ename||','||v_data.sal);
		end loop;
		close my_cur;
		end;
	使用 while循环
		declare
		cursor my_cur is select * from emp;
		v_data emp%rowtype;
		begin
		open my_cur;
		fetch my_cur into v_data;--先抓取再循环 ,%found当没有对游标数据进行抓取的时候返回 null
		while my_cur%found
		loop  
		dbms_output.put_line(v_data.ename||','||v_data.sal);
		fetch my_cur into v_data;
		end loop;
		close my_cur;
		end;
	使用 for循环 (遍历游标,不用显示打开游标,抓取游标,关闭游标)
		declare
		cursor my_cur is select * from emp;
		v_data emp%rowtype;
		begin
		for i in my_cur loop
		dbms_output.put_line(i.ename||','||i.sal);
		end loop;
		end;
	
	游标变量
		declare
		type cur_type is ref cursor;--定义类型为参照类型 
		v_data cur_type;--定义变量,类型为定义的类型 
		v_ar emp%rowtype;
		begin
		open v_data for select * from emp;
		loop--使用循环处理游标
		fetch v_data into v_ar;
		exit when v_data%notfound;
		dbms_output.put_line(v_ar.ename);
		end loop;
		close v_data;
		end;
	   编写一个过程,传入表名,返回所有数据 

	java调用存储过程
		1、调用没有参数的存储过程
		2、有输入参数
		3、有输入参数,输出参数
		4、输出参数为游标类型

	--使用存储过程实现oracle分页,并在JAVA中调用 
	  --oracle分页 rownum(mysql:limit,sql server:top)  不能用 minus xxxxxx  
	  pageSize(5)  
	  pageCurrent(3) 
	  pageSize*pageCurrent
	  (pageCurrent-1)*pageSize+1   
	  select * from emp;
	  select e.*,rownum rn from(select * from emp) e;
	  select e.*,rownum rn from(select * from emp) e where rownum<=10
	  select * from(select e.*,rownum rn from(select * from emp) e where rownum<=10) where rn>=6;   
	  --创建程序包,包中定义游标类型 
	  create or replace package package03 is
	  type cur_type is ref cursor;
	  end;
	  --存储过程   
	  create or replace procedure page_pro(
	  table_name varchar2,
	  pageSize in number,
	  pageCurrent in number,
	  v_data out package03.cur_type,
	  maxpage out number)
	  is
	  v_page_sql varchar2(500);
	  v_counts number(6);
	  v_sql varchar2(50);
	  begin
	  v_page_sql:='select * from(select e.*,rownum rn from(select * from '||table_name||') e where rownum<='||pageSize*pageCurrent||') where rn>='||((pageCurrent-1)*pageSize+1);
	  open v_data for v_page_sql; 
	  v_sql:='select count(*) from '||table_name;
	  execute immediate v_sql into v_counts;--execute,immediate立即执行 sql语句 
	  if mod(v_counts,pageSize)=0 then
	  maxpage:=v_counts/pageSize;
	  else
	  maxpage:=v_counts/pageSize+1;
	  end if;  
	  end;    
	  --JDBC调用存储过程 
		



	







		

		


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值