天天看点

**Orcale数据库 笔记2[共2篇]*

视图

1.语句:
	-- 查询语句创建表
	create table emp as select * from scott.emp;
	select * from emp;
	-- 创建视图[必须有dba权限]
	create view v_emp as select ename, job from emp;
	-- 查询视图
	select * from v_emp;
	-- 修改视图[不推荐]
	update v_emp set job='CLERK' where ename='ALLEN';
	-- 创建只读视图
	create view v_empl as select ename, job from emp with read only;
2. 视图的作用?
	-- 第一:视图可以屏蔽掉一些敏感字段
	-- 第二:保证总部和分部数据及时统一;[视图没有数据,数据是从总部获取的,当总部修改了后,分部就立即修改了]
           

索引

1. 索引的概念:索引就是在表的列上构建一个二叉树,达到大幅度提高查询效率的目的,但是索引会影响增删改的效率
2. 单列索引
	-- 创建单列索引
	create index idx_ename on emp(ename);
	-- 单列索引触发规则,条件必须是索引列中的原始值
	-- 单行函数,模糊查询,都会影响索引的触发
	select * from emp where ename='SCOTT';
3. 复合索引
	-- 创建复合索引
	create index idx_enamejob on emp(ename,job);
	-- 如果要触发复合索引,必须包含有优先检索列中的原始值
	select * from emp where ename='SCOTT' and job='xx';  -- 触发复合索引
	select * from emp where ename='SCOTT' or job='xx'; --不触发索引[一个触发,一个不触发,那么就是不触发索引了]
	select * from emp where ename='SCOTT';  -- 触发单列索引。 
           

pl/sql编程语言

1. 概述:
	-- pl /sql 编程语言
	-- pl/sql 编程语言是对sql语言的扩展,使得sql语言具有过程化编程的特性。
	-- pl/sql 变成语言比一般的过程化编程语言,更加灵活高效。
	-- pl/sql编程语言主要用来编写存储过程和存储函数等。

2. 声明方法
-- 赋值操作可以使用:= 也可以使用查询语句赋值
	declare
		i number(2):=10;
		s varchar2(10):='小明';
		ena emp.ename%type;		  -- 引用型变量
		emprow emp%rowtype;			-- 记录型变量  【查询一行的记录】	
	begin
		dbms_output.put_line(i);
		dbms_output.put_line(s);
		select ename into ena form emp where empno=7788;	
		dbms_output.put_line(ena);
		select * into emprow form emp where empno=7788;
		dbms_output.put_line(emprow.ename || '的工作为'	|| emprow.job);			//在orcale中连接符不是+ ,而是||
	end;


3. pl/sql中的if判断
	-- 输入小于18的数字,输出未成年
	-- 输入大于18 小于40的数字,输出中年人
	-- 输入大于40的数字,输出老年人
	
	declare
		i number(3):=ⅈ
	begin 
		if i<18 then
			dbms_output.put_line('未成年');
		elsif i<40 then
			dbms_output.put_line('中年人');
		else
			dbms_output.put_line('老年人');
		end if;
	end;


4. pl/sql中的loop循环
	1. 用三种方式输出1到10 十个数字
		1. while循环
			declare
				i number(2):=1;
			begin
				while i<22 loop
					dbms_output.put_line(i);
					i:=i+1;
				end loop;
			end;


		2. exit 循环				//工作中用的多,掌握
			declare
				i number(2):=1;
			begin
				loop
					exit when i>10;
					i:i+1;
				end loop;
			end;


		3. for循环
		
			declare
			
			begin
				for i in 1..10 loop
					dbms_output.put_line(i);
				end loop;
			end;


5. 游标:可以存放多个对象,多行记录。
	-- 输出emp表中所有员工的姓名
		declare
			cursor cl is select * from emp;
			emprow emp%rowtype
		begin
			open c1;
				loop
					fetch c1 into emprow;
					exit when c1%notfound;
					dbms_output.put_line(emprow.ename);
				end loop;
			close c1;
		end;

	-- 给指定部门员工涨工资
		declare
			cursor c2(eno emp.deptno%type) is select empno from emp where deptno=eno;
			en emp.empno%type;
		begin
			open c2(10);
				loop 
					fetch c2 into en; 
					exit when c2%notfound;
					update emp set sal=sal+100 where empno=en;
					commit;
				end loop;
			close c2;
		end;
	
	-- 查询10号部门员工信息
		select * from emp where deptno =10;
           

存储过程

1.概述:
	* 存储过程:存储过程就是提前已经编译好的一段pl/sql语言,放置在数据库端,可以直接被调用。这一段pl/sql一般都是固定步骤的业务。   
	* 不能写太复杂的业务,不然维护起来会很麻烦;

2. 创建存储过程的语法:
	create [or replace] procedure 过程名[(参数名 in/out 数据类型)]
	as
	begin
		PLSQL子程序体;
	end;

  或者
	create [or repalece]procedure 过程名[(参数名 in/out 数据类型)]
	is
	begin
		PLSQL子程序体;
	end 过程名;

3.示例:
	-- 给指定员工涨100块钱
		create or replace procedure pl(eno emp.empno%type)    -- 写上replace如果有其他的同名字的该代码可以覆盖,建议加上;
		is 
		
		begin
			update emp set sal=sal+100 where empno=eno;
			commit;
		end;
		
		select * from emp where empno=7788
	-- 测试p1 
		declare
		
		begin
			p1(7788);
		end;

	-- orcale语法严格,分号也必须加,不然会报错;
	-- 创建了存储过程的语句,无论关机后重启打开软件,都能在Procedures目录下找到该存储过程的文件;
           

存储函数

1. 语法:
	create or replace function 函数名(Name in type, Name in type,...)return 数据类型 is 结果变量 数据类型;
	begin 
	return(结果变量);
	end 函数名;

	-- 通过存储函数实现计算,指定员工的年薪
	-- 存储过程和存储函数的参数都不能带长度
	-- 存储函数放在Functions目录下
	-- 存储函数的返回值类型不能带长度
2.示例:
	create or replace function f_yearsql(eno emp.empno%type) return number
	is
		s number(10);
	begin
		select sal*12+nvl(comm,0) into s from emp where empno=eno;
		return s;
	end;

3. 测试f_yearsal
	-- 存储函数在调用的时候,返回值需要接收
	declare
		s number(10);
	begin
		s:=f_yearsal(7788)
		dbms_output.put_line(s);
	end;

4. out类型参数如何使用
	-- 使用存储过程来算年薪
	create or replace procedure p_yearsal(eno emp.empno%type, yearsal out number)
	is
		s number(10);
		c emp.comm%type;
	begin
		select sal*12, nvl(comm,0) into s,c from emp where empno=eno;
		yearsal:=s+c;
	end;

5. 测试p_yearsal(7788,yearsal);
	declare
		yearsal number(10);
	begin
		p_yearsal(7788,yearsal);
		dbms_output.put_line(yearsal);
	end;

-- in和out类型的参数的区别是什么?
-- 凡是涉及到into查询语句赋值或者 := 赋值操作的参数,都必须使用out来修饰;



-- 存储过程和存储函数的区别?
-- 语法区别:1.关键字不一样  2. 存储函数比存储过程多了两个return
-- 本质区别:存储函数有返回值,而存储过程没有返回值
-- 如果储存过程想实现有返回值的业务,我们就必须使用out类型的参数
-- 即便是存储过程使用了out类型的参数,其本质也不是真的有了返回值
-- 而是在存储过程内部给out类型参数赋值,在执行完毕后,我们直接其返回值操作。

6.自定义函数
	-- 我们可以使用存储函数有返回值的特性,来自定义函数。
	-- 而存储过程不能用来自定义函数。 
	-- 案例需求:查询出员工姓名,员工所在部门名称。
	-- 案例准备工作:把scott用户下的dept表复制到当前用户下
	crate table dept as select * from soctt.dept;
	-- 使用传统方式来实现案例需求
	select 
	from emp e; dept d
	where e.deptno=d.deptno;
	
	-- 使用存储函数来是西安提供一个部门编号,输出一个部门名称。
	create or replace function fdna(dno dept.deptno%type) return dept.dname%type
	is 
		dna dept.dname%type;
	begin
		select dname into dna from dept where deptno=dno;
		return dna;
	end;
	
	-- 使用fdna存储函数来实现案例需求
	select e.ename,fdna(e.deptno)		-- 这里fdna调用了上面存储过程方法
	from emp e;
	
	
	
	-- 存储过程和存储函数相当于java中的方法,存储过程用来增删改,存储函数可以用来做查询;
           

触发器

1.概述:
	-- 触发器,就是指定一个规则,在我们做增删改操作的时候,只要满足该规则,自动触发,无需调用。   查询的时候不会调用到触发器;
	-- 语句级触发器:不包含有for each row的触发器
	-- 行级触发器:包含有for each row 的就是行级触发器
	--- 加for each row 为了使用 :old 或者 :new 对象或者一行记录。
	-- 数据中的一行数据对应java中的对象 
	
	-- insert 的 :old 是所有字段为null,:new 之后就有了新的数据
	-- Update 的	 :old 是更新以前该行的值, :new 是更新后的值
	-- delete 的 :old 是删除之前该行的值, :new 是所有字段都为null
2.示例:
	1. 语句级触发器:
	-- 插入一条记录,输入一个新员工入职		//触发器示例
		create or replace trigger t1 
		after
		insert
		on person
		declare
		
		begin
			dbms_output.put_line('一个新员工入职');
		end;

	
	-- 触发t1
		insert into person values(1,'小红');
		commit;
	
	-- 查询
		select * from person;


	2. 行级触发器
	-- 不能给员工降薪
	-- raise_application_error()
		create or replace tigger t2
		before 
		update
		on emp
		for each row
		declare
		
		begin
			if:old.sal>:new.sal then
				raise_application_error(-200001,'不能给员工降薪')
			end if;   
		end;
	
	
	-- 触发t2
		update emp set sal=sal-1 where empno =7788;
		commit;
	-- 查询	
		select * form emp where empno=7788;


3. 触发器实现主键自增。[行级触发器]
	-- 分析:在用户做插入操作之前,拿到即将插入的数据。
	-- 给该数据中的主键列赋值。
		create or replace tigger auid
		before
		insert
		on person
		for each row
		declare
		
		begin
			select s_person.nextval into :new.pid from dual;
		end;
	
	-- 查询person表数据
		select * from person;
	-- 使用auid实现主键自增
		insert into person (pname) values ('a');
		commit;




4. 使用java调用orcale中的存储过程和存储函数
	-- orcale10g  ojbdc14.jar
	-- orcalel11g  ojdbc6.jar
	
	
	示例:
		1. 创建一个maven工程   gid:com.itheima	aid:jdbc_orcale
		2. Maven projects need to be imported?[是否自动导入]  ->Enable Auto-Import  确定自动导入
		3. pom.xml导入角标:[ojdbc14/runtime,junit/test]
		4. test.java.com.itheima.orcale.OrcaleDame:创建该类:
			* public class OrcaleDemo{
			* @Test
			* public void javaCa11Orcale() throws Exception{
			* //加载数据库驱动
			* Class.forName("orcale.jdbc.driver.OrcaleDriver")
			* //得到connection连接
			* Connection connection=DriverManager.getConnection("jdbc:orcale:thin:@192.168.88.6:1521:orcale",scott,tiger)
			* //得到预编译的Statement对象
			* CallableStatement pstm=connection.prepareCall("{call p_yearsal(?,?)}");
			* //给参数赋值
			* pstm.setObject(1,7788);
			* pstm.registerOutParameter(2,OracleType.NUMBER);
			* //执行数据库查询操作
			* pstm.execute();
			* //输出结果
			* System.out.println(pstm.getObject("2"));
			* pstm.close();
			* }
           

java调用存储过程和存储函数

1.接口:CallableStatement
	*  {?=call<procedure-name>[(<arg1>,<arg2>,...)]} 			调用存储函数使用
	*  {call<procedure-name>[(<arg1>,<arg2>,...)]} 		调用存储过程使用。
	
2. 示例:
	* public class OrcaleDemo{
	* @Test
	* public void javaCa11Orcale() throws Exception{
	* //加载数据库驱动
	* Class.forName("orcale.jdbc.driver.OrcaleDriver")
	* //得到connection连接
	* Connection connection=DriverManager.getConnection("jdbc:orcale:thin:@192.168.88.6:1521:orcale",scott,tiger)
	* //得到预编译的Statement对象
	* PreparedStatement pstm=connection.prepareStatement("select * from emp where empno=?");
	* //给参数赋值
	* pstm.setObject(1,7788);
	* //执行数据库查询操作
	* ResultSet rs=pstm.executeQuery();
	* //输出结果
	* while(rs.next){
	* System.out.println(rs.getString("ename"));
	* }
	* }