视图:一个虚拟表,就是说在数据库中不以数据值得形式存在,但是他又有行列等,可以供用户查询,他是一个表的映射。
视图主要完成两个功能:
1, 把多张表里的数据映射到一张虚拟表中,这样,查多张表,就变成了查一个视图。视图可以由自己事先向编写存储过程一样生成,这样我们就可以时刻查询这个视图了;
2, 既然可以把多张表中的内容映射到一张虚拟表中,那么我们完全可以,把部分私密数据不映射到虚拟表中,然后赋予某些用户访问不同虚拟表也就是视图的权限,达到权限分配的目的;
视图与表的区别:
1, 表需要占用磁盘空间,视图不需要;
2, 视图不能添加索引,缺点。
3, 视图可以简化复杂查询;
4, 视图有利于提高安全性;比如,不同用户查看不同视图;
怎么创建视图:
create or replace view gpz as select empno from emp; //创建名为gpz的视图,查询该视图,可以查询到empno
后面加上with read only : 只能查询,不能修改视图
删除视图
Drop view gpz;
触发器:
触发器是系统或者我们自己定义的当执行一个操作时,另外一系列的操作会随之而执行的过程,他其实也是个存储过程;
触发器分类:
Dml(select insert,update)触发器:
Ddl(数据定义语言)(create table create view …drop..)触发器:
系统触发器(用户登入,退出,启动,关闭数据库): 只能有sysdba来创建的触发器。
需要用到触发器而解决的问题:
1,当用户登入到oracle时,在一张表中记录该用户的登陆信息,要用到系统触发器;
2,禁止用户在休息日对某张表进行删除操作要用到dml或者ddl触发器;
3,当用户删除一张表时,自动把删除记录备份到另外一张表中,也可以用dml或者ddl触发器;
创建触发器的语法:
Create or replace trigger 触发器名字
Before/after
Insert/delete/update /drop/logon… [of column [column…]]
On [schema.]表
[For each row]
When 条件
Begin
Trigger_body
End;
首先,介绍dml触发器:进行(select insert,update)引发的操作;
例子:在某张表上添加一条数据时,提示‘添加了一个记录’;
set serveroutput on;
创建触发器;
create or replace trigger tri1
after insert on emp
begin
--dbms_output.put_line('添加了一条记录');
raise_application_error(-20001,'添加了一条记录');--这句表示一个过程,参数1:错误代号,范围(20000-29999),参数2:提示的错误信息;
end;
例2:在表中修改了几条记录,就提示修改了几条记录;
//利用行级和语句级触发器:
Create or replace trigger tri2
After update on scott.emp
For each row –行级触发器 ---要想对每条数据做修改都能监测到,就要用到for each row;
Begin
--Dbms_output.putline(‘修改了一条记录’); 可以不要这条语句
raise_application_error(-20002,'修改了一条记录');
End;
例3:禁止dba在星期天修改数据;
Create or replace trigger tri3
Before delete on scott.emp
Begin
If to_char(sysdate,’day’) in (‘星期日’,’星期六’) then
--Dbms_output.put_line(‘这两天不能删除员工’);
Raise_application_error(-20003,’对不起,不鞥删除!’);
End if;
End;
当在设计一个触发器时,有对表进行insert,update,delete多个操作时,可以用到条件谓词,配合case …when.. 达到提示用户到底执行了什么操作的目的;
条件谓词有 inserting, updating, deleting .
谓词使用举例:监测开发人员对表进行了何种处理:
create or replace trigger tri3
before
insert or update or delete on emp
begin
case
when inserting then
raise_application_error(-20002,'不能添加');
when updating then
raise_application_error(-20003,'不能修改');
when deleting then
raise_application_error(-20004,'不能删除');
endcase;
end;
有时会遇到这样的情况:用到修改,插入,删除的新值和旧值;
可以使用:old和:new;
案例:在修改emp表的雇员薪水时,显示雇员工资的修改前后的值,要确保他的工资不低于原工资;
create or replace trigge rtri4
before update on emp
for each row
begin
if :new.sal<:old.sal then
raise_application_error(-20005,'工资不能低于原来的工资!');
else
dbms_output.put_line('原来的工资是'||:old.sal||'现在的工资是'||:new.sal);
endif;
end;
/
可以检测一下这个触发器是否编写正确:update emp set sal=1 where ename='SCOTT'
例子:在删除前把删除的内容备份一个到emp_bak;
create or replace trigger tri4
before delete on emp
for each row
begin
insert into emp_bak(id ,name) values(:old.empno,:old.ename);
end;
/
系统触发器:主要针对oracle事件:logon logoff startup shupup建立的触发器; 注意这种系统触发器只能由sysdba来建立
Oracle预定义了一些时间属性函数:
Ora_client_ip_address //返回客户端的ip
Ora_database_name //返回数据库名
Ora_longin_user ///返回登录用户名
Ora_sysevent //返回触发器的系统事件名
Oral_des_encrypted_password //返回用户des(md5)加密后的密码
例子:建立一张表,用来记录用户登入,退出的用户名,时间,ip地址)
建立记录表log_table
Create table log_table(uname varchar2(30) ,logon_time varchar2(30),logoff_time varchar2(30),addvarchar2(50));
创建登入触发器:
create or replace trigger tri4 //创建登入触发器
after logon on database
begin
insert into log_table(uname, logon_time, add) values (Ora_longin_user,sysdate, Ora_client_ip_address);
end;
ddl触发器:由于数据定义语言create,alter,drop等触发的过程:
例子:建立一张表来存取那个用户建立了表:
Create table my_ddl_record(event varchar2(64),unane varchar2(64),ddl_time date);
//创建ddl触发器
Create or replace trigger tri5
After ddl onscott.schema --///注意这里是用的ddl代替了所有的ddl语言
Begin
Insert into my_ddl_record values(ora_sysevent,ora_login_user,sysdate);
End;
3种触发器已经都介绍完毕,另外需注意的是dml触发器,要生效,最好手动提交一下,也就是commit,因为他不会自动提交,只会在退出时提交; ddl和系统触发器可以自动提交。
管理触发器:
要管理触发器一般使用system登入:
禁止触发器:alter trigger disable
激活触发器:Alter trigger 触发器名 enable;
禁止或者激活所有表的所有触发器:Alter table emp disable/enable all triggers; (对于9i)
删除触发器:drop trigger 触发器名