1、【视图】
--查询语句创建表
create table emp as select * from scott.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';
commit;
--创建只读视图
create view v_empl as select ename ,job from emp with read only;
--视图的作用
--1.视图可以屏蔽掉一些敏感字段
--2.保证总部和分布数据及时统一
2、【索引】
--索引的概念:索引就是在表的列上构建一个二叉树
--达到大幅度提高查询效率的目的,但是索引不会影响增删改的目的
--创建单列索引
create index idx_ename on emp(ename);
--单列索触发规则,条件必须是索引列中原始值
--单列函数,模糊查询,都会影响索引的触发
select * from emp where ename = 'SCOTT';
--复合索引
--创建复合索引
create index idx_enamejob on emp(ename,job);
--复合索引第一列为有限检索列
--如果要出发复合索引,必须包含有优先检索列中的原始值
select * from emp where ename='SCOTT' and job='ANALYST';--触发复合索引
select * from emp where ename='SCOTT' or job='ANALYST';-- 不触发索引
select * from emp where ename='SCOTT';--触发单列索引
3、【pl/sql 编程语言】
--声明方法
--赋值操作可以使用:=也可以使用into查询语句赋值
--编码块的结果--打开命令行窗口->执行set serveroutput on;->代码块编写完毕输入“/”
declare
i number(2) :=10;
s varchar(10) :='小明';
ena emp.ename%type;--引用型变量
emprow emp%rowtype;--记录型变量
begin
dbms_output.put_line(i);
dbms_output.put_line(s);
select ename into ena from emp where empno = 7788;
dbms_output.put_line(ena);
select * into emprow from emp where empno = 7788;
dbms_output.put_line(emprow.ename||'的工作为:'|| emprow.job);
end;
---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;
--pl/sql中的loop循环
--用三种方式输出1到10个数字
--while循环
declare
i number(2) :=1;
begin
while i<11 loop
dbms_output.put_line(i);
i :=i+1;
end loop;
end;
--exit循环
declare
i number(2) :=1;
begin
loop
exit when i>10;
dbms_output.put_line(i);
i:=i+1;
end loop;
end;
--for循环
declare
begin
for i in 1..10 loop
dbms_output.put_line(i);
end loop;
end;
--游标:可以存放多个对象,多行记录
--输出emp表中所有员工的姓名
declare
cursor c1 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;
--存储过程:编译好的sql语句集合,可以直接调用
--栗子:给指定员工涨100块钱
create or replace procedure p1(eno emp.empno%type)
is
begin
update emp set sal=sal+100 where empno = eno;
commit;
end;
select * from emp where empno = 7788;
--测试
declare
begin
p1(7788);
end;
--存储函数
--存储过程无返回值 存储函数带返回值的
--%type:获取字段类型/ %notfound结束标志
--栗子:存储函数计算指定员工的年薪
create or replace function f_yearsal(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;
--测试f_yearsal
--存储函数在调用的时候,返回值需要接受。
declare
s number(10);
begin
s := f_yearsal(7788);
dbms_output.put_line(s);
end;
--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;
--测试p_yearsal
declare
yearsal number(10);
begin
p_yearsal(7788,yearsal);
dbms_output.put_line(yearsal);
end;
--in和out类型参数的区别是什么?
--凡是涉及到into查询语句赋值或者:=赋值操作的参数,都 必须使用out来修饰
--存储过程和存储函数的区别
--语法区别:关键字不一样
-------存储函数比存储国车给多了两个return
--本质区别:存储函数有返回值,而存储过程没有返回值
-------如果存储过程想实现有返回值的业务,我们就必须使用out类型的参数
-------即便是存储过程使用了out类型的参数,其本质也不是真的有了返回值
-------而是在存储过程内部给out参数参数赋值,在执行完毕后,我们直接拿到输出类型参数的值
---我们可以使用存储函数有返回值的特性,来自定义函数
--而存储过程不能用来自定义函数
--案例需求:查询出员工姓名,员工所在部门名称
--案例准备工作:把scott用户下的dept表赋值到当前用户下
create table dept as select * from scott.dept;
--使用传统方式来实现案例需求
select e.ename,d.dname 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,dna(e.deptno)
from emp e;
--触发器,就是制定一个规则,在我们做增删改 操作的时候,
--只要满足该规则,自动触发,无需调用。
--语句级触发器:不包含有for each row的触发器
--行级触发器:包含有for each row的就是行级触发器
----加for each row是为了使用:old 或者:new对象或者一行记录
--语句级触发器
--插入一条记录,输出一个新员工入职
create or replace trigger t1
after insert on
tab_user
declare
begin
dbms_output.put_line('一个新员工入职');
end;
--触发t1
insert into tab_user values(1,'小红');
commit;
select * from tab_user;
--行级别触发器
--不能给员工降薪
--raise_application_error(-20001~-20999之间,‘错误提示信息’)
create or replace trigger t2
before update on
emp
for each row
declare
begin
if :old.sal>:new.sal then
raise_application_error(-20001, '不能给员工降薪');
end if;
end;
--触发t2
select * from emp where empno = 7788;
update emp set sal = sal-1 where empno =7788;
commit;
--触发器实现主键自增【行级触发器】
--分析:在用户做插入操作之前,拿到即将插入的数据
--给该数据中的主键列赋值。
create sequence s_iuser;
create or replace trigger auid
before
insert
on tab_user
for each row
declare
begin
select s_iuser.nextval into :new.id from dual;
end;
--查询tab_user表数据
select * from tab_user;
--使用auid实现主键自增
insert into tab_user(uname) values('a');
commit;
insert into tab_user values(1,'b');
commit;
--java 调用存储过程
---oracle10g ojdbc14.jar
---oracle11g ojdbc6.jar