码迷,mamicode.com
首页 > 数据库 > 详细

ORACLE 索引、视图、游标、存储过程和触发器

时间:2015-06-15 15:57:45      阅读:209      评论:0      收藏:0      [点我收藏+]

标签:

1 索引 

      目标是为了提高查询的速度,当用户对查询速度不满意而需要对数据库的性能进行调校时,优先考虑建立索引。       

数据库中索引的概念与书索引的概念非常类似,不同之处在于数据库索引用来在表中查找特定的行。       

索引缺点:向表中“添加/删除”行时,必须花费额外的时间来更新该行的索引。       

创建索引的时机:当需要从大表中检索少数几行时,都应该对列创建索引。       

基本准则:当任何单个查询要检索的行<=整个表行数的10%时,索引就非常有用。自动创建索引:表的主键和唯一键将自动创建索引 。

1.1 语法  

create [unique] index 索引名 -------unique指定索引列中的值是唯一的,索引名建议以idx打头 

on 表名(列1, 列2... ...) --------可以对多列创建索引,这种索引称为“复合索引”       

[tablespace 表空间名]; --------省去后,索引将被存储到用户的默认表空间中       

提示:出于性能方面的原因,通常应该将索引与表存储到不同的表空间中。示例: create index idx_customers_lastname on customers(last_name);

1.2 查询索引和索引列的信息

select * from user_indexes where table_name in(‘CUSTOMERS‘, ‘EMPLOYEES‘);

1.3 修改索引 

  alter index 索引名 rename to 新索引名。

1.4 删除索引

  drop index 索引名。

2.视图(VIEW)

2.1 概念 

     视图-----是由SELECT查询语句(可以是单表或者多表查询)定义的一个"逻辑表",只有定义而无数据,是一个"虚表". 在创建视图时,只是将视图的定义信息

保存在数据字典中, 而并不将实际的数据复制到任何地方, 即不需要在表空间中为视图分配存储空间. 视图是查看和操纵基表数据的一种方法, 可以像使用表一

样使用视图。所有针对视图的操作都会影响到视图的基表; 为了防止用户通过视图间接修改基表的数据, 可以将视图创建为只读视图(带上with read only选

项)。视图中的数据会随基表的更新而自动更新。视图犹如基表的一个"窗口", 通过这个"窗口", 可以实施许多管理. 在一个视图中可以定义的最大列数为1000,

与表的限制相同。视图约束: 允许在视图上生成约束, 如"主键约束、唯一键约束、外键约束、检查约束"等。 视图约束的语法与表相同. 在创建视图时, 可以使

用with check option选项,给视图定义check约束,使其只能查询、操作满足check约束的记录行。

2.2 作用   

1)提供各种数据表现形式, 可以使用各种不同的方式将基表的数据展现在用户面前, 以便符合用户的使用习惯(主要手段: 使用别名).           

2)执行某些必须使用视图的查询. 某些查询必须借助视图的帮助才能完成. 比如, 有些查询需要连接一个分组统计后的表和另一表, 这时就可以先基于分组统计

的结果创建一个视图, 然后在查询中连接这个视图和另一个表就可以了。 

3)提供某些安全性保证. 视图提供了一种可以控制的方式, 即可以让不同的用户看见不同的列, 而不允许访问那些敏感的列, 这样就可以保证敏感数据不被用户

看见。

2.3 创建视图  

权限: 要在当前方案中创建视图, 用户必须具有create view系统权限; 要在其他方案中创建视图, 用户必须具有create any view系统权限. 视图的功能取决于

视图拥有者的权限。

语法: create [ or replace ] [ force ] view [schema.]view_name  [ (column1,column2,...) ]

as select ...     [ with check option ] [ constraint constraint_name ]   [ with read only ];

解释: or replace: 如果存在同名的视图, 则使用新视图"替代"已有的视图 force: "强制"创建视图,不考虑基表是否存在,也不考虑是否具有使用基表的权限  col

umn1,column2,...:视图的列名, 列名的个数必须与select查询中列的个数相同; 如果select查询包含函数或表达式, 则必须为其定义列名. 此时, 既可以用col

umn1, column2指定列名, 也可以在select查询中指定列名。with check option: 指定对视图执行的dml操作必须满足“视图子查询”的条件即,对通过视图

进行的增删改操作进行"检查",要求增删改操作的数据, 必须是select查询所能查询到的数据, 否则不允许操作并返回错误提示。with read only:创建的视图只

能用于查询数据, 而不能用于更改数据。

创建一个简单视图的示例:基于emp表创建一个vw_emp视图  create view vw_emp     as    select empno,ename,job,hiredate,deptno from em

p; desc vw_emp; --------象表一样使用        

select * from vw_emp where deptno=10;--------查询

insert into vw_emp values(1234,‘JACK‘,‘CLERK‘,‘29-4月-1963‘,10);--------增加         

update vw_emp set ename=‘刘德华‘ where ename=‘JACK‘;--------更新         

delete vw_emp where ename=‘刘德华‘; --------删除

2.4 删除视图  

可以删除当前模式中的任何视图; 如果要删除其他模式中的视图,必须拥有DROP ANY VIEW系统权限;视图被删除后,该视图的定义会从词典中被删除,

并且在该视图上授予的“权限”也将被删除。视图被删除后,其他引用该视图的视图及存储过程等都会失效。示例1:drop view vw_test_tab;

2.5 查看视图   

示例1:查询当前方案中所有视图的信息   desc user_views;  set long 400; select view_name,text from user_views;        

示例1:查询当前方案中指定视图(或表)的列名信息   select * from user_tab_columns where table_name=‘VW_DEPT‘;

3 游标

游标是一段私有的SQL工作区,是一段内存区域。用于存放收SQL语句影响的数据,是一个虚表。

3.1、需要游标的数据操作

当select语句的结果中包含多个元组时,使用游标可以逐个存取这些元组。

活动集:select语句返回的元组的集合

当前行:活动集中当前处理的那一行。游标即是指向当前行的指针。

3.2、游标分类

滚动游标:游标的位置可以来回移动,可在活动集中取任意元组。

非滚动游标:只能在活动集中顺序地取下一个元组。

更新游标:数据库对游标指向的当前行加锁,当程序读下一行数据时,本行数据解锁,下一行数据加锁。

3.3、定义与使用游标的语句

declare :

declare 游标名[scroll] cursor for select语句[for update [of列表名]]

定义一个游标,使之对应一个select语句

for update任选项,表示该游标可用于对当前行的修改与删除

open

打开一个游标,执行游标对应的查询,结果集合为该游标的活动集

open 游标名

fetch

在活动集中将游标移到特定的行,并取出该行数据放到相应的变量中

fetch [next | prior | first | last | current | relative n | absolute m] 游标名into [变量表]

close

关闭游标,释放活动集及其所占资源。需要再使用该游标时,执行open语句

close 游标名

deallocate

删除游标,以后不能再对该游标执行open语句

deallocate游标名

@@FETCH_STATUS

返回被FETCH语句执行的最后游标的状态.

0 fetch语句成功

-1 fetch语句失败

-2 被提取的行不存在

例:查询电子商务系学生信息,性别为女输出为female,否则输出为male?

declare c1 cursor for select sno,sname,ssex from student where sdept=‘ec‘

declare @sno char(10),@sname char(10),@ssex char(2)

Open c1

Fetch c1 into @sno,@sname,@ssex

While @@fetch_status==0

Begin

if @ssex=‘女‘

begin set @ssex=‘female‘ end

else

begin set @ssex=‘male‘ end

Select @sno,@sname ,@ssex

Fetch c1 into @sno,@sname,@ssex

end

4,存储过程

4.1定义

:是在大型数据库系统中,一组为了完成特定功能的SQL 语句集,经编译后存储在数据库中,用户通过指定存储过程的名字并给出参数(如果该存储过程带有参数)来执行它。

4.2格式

create or replace procedure 存储过程名(param1 in type,param2 out type)

as

变量1 类型(值范围);

变量2 类型(值范围);

Begin

语句块

Exception --异常处理

When others then

Rollback;

End;

4.3注意事项:

a,存储过程一般用来完成数据查询和数据处理操作,所以在存储过程中不可以使用创建数据库对象的语句。

b,存储过程中的参数: IN表示向存储过程传递参数;OUT表示从存储过程返回参数;IN OUT 表示传递参数和返回参数;

4.4使用示例

定义:

create or replace procedure WithParPro (para_1 IN NUMBER,para_2 OUT NUMBER,para_3 IN out NUMBER)

AS

temp1 NUMBER(20);

BEGIN

temp1:=para_1+10;

IF temp1<para_3 THEN para_2:=para_3;

ELSE

para_2:=temp1;

END IF;

Dbms_Output.put_line(para_2);

EXCEPTION

WHEN OTHERS THEN

ROLLBACK;

END;

执行该存储过程:

declare

v_temp1 number(10);

v_temp2 number(10);

begin

v_temp2:=10;

withparpro(1,v_temp1,v_temp2);

end;

/

5,触发器

触发器就是特殊的存储过程,特殊在,触发器不需要通过人为(例:在程序中调用)的操作来启动它,触发器的启动是由事件(删除、更新等)的执行来自动

启动的。

5.1、定义格式

CREATE [OR REPLACE] TRIGGER trigger_name

{BEFORE | AFTER }

{INSERT | DELETE | UPDATE [OF column [, column …]]}

[OR {INSERT | DELETE | UPDATE [OF column [, column …]]}...]

ON [schema.]table_name | [schema.]view_name

[REFERENCING {OLD [AS] old | NEW [AS] new| PARENT as parent}]

[FOR EACH ROW ]

[WHEN condition]

PL/SQL_BLOCK | CALL procedure_name;

5.2、触发器分类

插入类触发器…insert;删除类触发器…delete;更新类触发器…update

5.3、DML触发器基本要点

触发时机指定触发器的触发时间。如果指定为BEFORE,则表示在执行DML操作之前触发,以便防止某些错误操作发生或实现某些业务规则;如果指定为AF

TER,则表示在执行DML操作之后触发,以便记录该操作或做某些事后处理。

触发事件引起触发器被触发的事件,即DML操作(INSERT、UPDATE、DELETE)。既可以是单个触发事件,也可以是多个触发事件的组合(只能使用OR

逻辑组合,不能使用AND逻辑组合)。

条件谓词当在触发器中包含多个触发事件(INSERT、UPDATE、DELETE)的组合时,为了分别针对不同的事件进行不同的处理,需要使用ORACLE提供

的如下条件谓词。

1),INSERTING:当触发事件是INSERT时,取值为TRUE,否则为FALSE。

2),UPDATING [(column_1,column_2,…,column_x)]:当触发事件是UPDATE时,如果修改了column_x列,则取值为TRUE,否则为FALSE。

其中column_x是可选的。

3),DELETING:当触发事件是DELETE时,则取值为TRUE,否则为FALSE。

解发对象:指定触发器是创建在哪个表、视图上。

触发类型:是语句级还是行级触发器。

触发条件:由WHEN子句指定一个逻辑表达式,只允许在行级触发器上指定触发条件,指定UPDATING后面的列的列表。

5.4编写触发器时,需要注意的地方:

触发器不接受参数。

一个表上最多可有12个触发器,但同一时间、同一事件、同一类型的触发器只能有一个。并各触发器之间不能有矛盾。

在一个表上的触发器越多,对在该表上的DML操作的性能影响就越大。

触发器最大为32KB。若确实需要,可以先建立过程,然后在触发器中用CALL语句进行调用。

在触发器的执行部分只能用DML语句(SELECT、INSERT、UPDATE、DELETE),不能使用DDL语句(CREATE、ALTER、DROP)。

触发器中不能包含事务控制语句(COMMIT,ROLLBACK,SAVEPOINT)。因为触发器是触发语句的一部分,触发语句被提交、回退时,触发器也被提交、回

退了。

在触发器主体中调用的任何过程、函数,都不能使用事务控制语句。

在触发器主体中不能申明任何Long和blob变量。新值new和旧值old也不能是表中的任何long和blob列。

不同类型的触发器(如DML触发器、INSTEAD OF触发器、系统触发器)的语法格式和作用有较大区别。

5.5示例:

建立一个触发器, 当职工表 emp 表被删除一条记录时,把被删除记录写到职工表删除日志表中去。

 

CREATE TABLE emp_his AS SELECT * FROM EMP WHERE 1=2;

CREATE OR REPLACE TRIGGER tr_del_emp

BEFORE DELETE --指定触发时机为删除操作前触发

ON scott.emp

FOR EACH ROW   --说明创建的是行级触发器

BEGIN
--将修改前数据插入到日志记录表 del_emp ,以供监督使用。

INSERT INTO emp_his(deptno , empno, ename , job ,mgr , sal , comm , hiredate )

VALUES( :old.deptno, :old.empno, :old.ename , :old.job,:old.mgr, :old.sal, :old.comm, :old.hiredate );

END;

DELETE emp WHERE empno=7788;

DROP TABLE emp_his;

DROP TRIGGER del_emp;

ORACLE 索引、视图、游标、存储过程和触发器

标签:

原文地址:http://www.cnblogs.com/kangronglong/p/4577021.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!