当前位置:  数据库>oracle
本页文章导读:
    ▪Oracle触发器1-介绍      Oracle官方参考:PL/SQL Language Referenc->9 PL/SQL Trigger Reasons to Use Trigger: ■ Automatically generate calculated column values  ■ Log events ■ Gather statistics on table access ■ Modify table data when DML statements .........
    ▪Oracle触发器2-DML触发器        DML触发器是最常见的触发器类型,开发人员用的比较多;而其他类型的触发器主要是用于数据库管理或者审计,DBA用的比较多。1、DML触发器简介:BEFORE 触发器这种触发器是在某个操作发.........
    ▪Oracle编程入门经典 第8章 索引      目录8.1        索引工作方式... 18.2        Oracle中的索引... 18.3        索引什么时候有用... 48.4     .........

[1]Oracle触发器1-介绍
    来源:    发布时间: 2013-10-29

Oracle官方参考:PL/SQL Language Referenc->9 PL/SQL Trigger

Reasons to Use Trigger:

■ Automatically generate calculated column values 
■ Log events
■ Gather statistics on table access
■ Modify table data when DML statements are issued against views
■ Enforce referential integrity when child and parent tables are on different nodes of a distributed database
■ Publish information about database events, user events, and SQL statements to subscribing applications
■ Prevent DML operations on a table after regular business hours
■ Prevent invalid transactions
■ Enforce complex business or referential integrity rules that you cannot define with constraints

本人E比较差,防止误导别人,也就不一一解释。

触发器在数据库里以独立的对象存储,它与存储过程和函数不同的是,存储过程与函数需要用户显示调用才执行,而触发器是由一个事件来启动运行。即触发器是当某个事件发生时自动地隐式运行。并且,触发器不能像存储过程一样接收参数。ORACLE事件指的是对数据库的表进行的INSERT、UPDATE及DELETE操作或对视图进行类似的操作。ORACLE将触发器的功能扩展到了触发ORACLE,如数据库的启动与关闭等。所以触发器常用来完成由数据库的完整性约束难以完成的复杂业务规则的约束,或用来监视对数据库的各种操作,实现审计的功能。

DML触发器

ORACLE可以在DML语句进行触发,可以在DML操作前或操作后进行触发,并且可以对每个行或语句操作上进行触发。

DDL触发器

同DML触发器类似。

替代触发器

由于在ORACLE里,不能直接对由两个以上的表建立的视图进行操作。所以给出了替代触发器。

数据库事件触发器

ORACLE 提供了第三种类型的触发器,数据库事件触发器也叫系统触发器。它可以在ORACLE数据库系统的事件中进行触发,如ORACLE系统的启动与关闭等。

      触发器组成部分

1、 触发器名称
2、 触发语句
3、 触发器限制
4、 触发操作

Trigger Design Guidelines:

■ Use triggers to ensure that whenever a specific event occurs, any necessary actions are done (regardless of which user or application issues the triggering statement).
For example, use a trigger to ensure that whenever anyone updates a table, its log file is updated.
■ Do not create triggers that duplicate database features.
For example, do not create a trigger to reject invalid data if you can do the same with constraints.
■ Do not create triggers that depend on the order in which a SQL statement processes rows (which can vary).
For example, do not assign a value to a global package variable in a row trigger if the current value of the variable depends on the row being processed by the row trigger. If a trigger updates global package variables, initialize those variables in a BEFORE statement trigger.
■ Use BEFORE row triggers to modify the row before writing the row data to disk.
■ Use AFTER row triggers to obtain the row ID and use it in operations.An AFTER row trigger fires when the triggering statement results in ORA-2292.

■ If the triggering statement of a BEFORE statement trigger is an UPDATE or DELETEstatement that conflicts with an UPDATE statement that is running, then the
database does a transparent ROLLBACK to SAVEPOINT and restarts the triggering statement. The database can do this many times before the triggering statement
completes successfully. Each time the database restarts the triggering statement, the trigger fires. The ROLLBACK to SAVEPOINT does not undo changes to package
variables that the trigger references. To detect this situation, include a counter variable in the package.
■ Do not create recursive triggers.
For example, do not create an AFTER UPDATE trigger that issues an UPDATE statement on the table on which the trigger is defined.

The trigger fires recursively until it runs out of memory

■ Use DATABASE triggers judiciously. They fire every time any database user initiates a triggering event.
■ If a trigger runs the following statement, the statement returns the owner of the trigger, not the user who is updating the table:
SELECT Username FROM USER_USERS;
■ Only committed triggers fire.
A trigger is committed, implicitly, after the CREATE TRIGGER statement that creates it succeeds.

Therefore, the following statement cannot fire the trigger that it creates:
CREATE OR REPLACE TRIGGER my_trigger
  AFTER CREATE ON DATABASE
BEGIN
  NULL;
END;
/
■ To allow the modular installation of applications that have triggers on the same tables, create multiple triggers of the same type, rather than a single trigger that
runs a sequence of operations.Each trigger sees the changes made by the previously fired triggers. Each trigger can see OLD and NEW values.

本文链接


    
[2]Oracle触发器2-DML触发器
    来源:    发布时间: 2013-10-29

  DML触发器是最常见的触发器类型,开发人员用的比较多;而其他类型的触发器主要是用于数据库管理或者审计,DBA用的比较多。

1、DML触发器简介:

BEFORE 触发器

这种触发器是在某个操作发生之前触发的,比如before insert就是在插入操作之前触发。

AFTER 触发器

这种触发器是在某个操作发生之后触发的,比如after update就是在插入操作之前触发。

语句级别触发器

这种触发器是由整个SQL语句触发的。这个SQL语句可能操作数据库表的一条或者多条数据。

行级别触发器

这种触发器针对的是SQL语句执行过程中操作的每一行记录。假设books表中有1000行记录。下面的update语句就会修改1000行记录:

update books set title = upper(title);

如果我在books表上定义了一个行级别的更新触发器,这个触发器就会被触发1000次。

伪记录 NEW

这是一个被叫做NEW的数据结构,看起来和PL/SQL中的记录非常相似。只有在更新操作和插入操作的DML触发器中才能使用这个伪记录;这个记录包含的是被操作的行修改之后的值。

伪记录 OLD

这是一个被叫做OLD的数据结构,看起来和PL/SQL中的记录非常相似。只有在更新操作和插入操作的DML触发器中才能使用这个伪记录;这个记录包含的是被操作的行修改之前的值。

WHEN 子句

DML触发器用这个子句来确定是否应该执行触发器的代码,我们可以用它来避免不必要的执行。

有关事务

DML触发器会参与到触发他们的事务中。

如果触发器抛出了异常,这部分事务会回滚(rollback)。

如果触发器本身也执行了DML语句(比如向日志表中插入一行数据),这个DML同时也会成为主体事务的一部分。

不能在DML触发器里执行commit或者rollback语句。

2、创建DML触发器

1 CREATE [OR REPLACE] TRIGGER trigger_name   --指定一个触发器名字, or replace 可选
2 {BEFORE | AFTER}     --指定触发器时机是在语句执行之前或者之后。
3 {INSERT | DELETE | UPDATE | UPDATE OF column_list } ON table_name --指定触发器应用的DML类型组合:插入、更新或者删除操作。
4 [FOR EACH ROW]   --如果指定了for each row 则语句处理的每一行记录都会激活触发器。
5 [WHEN (...)]            --通过这个可选的when子句,可以避免不必要的执行
6 [DECLARE ... ]  
7 BEGIN
8 ...executable statements...    --执行体
9 [EXCEPTION ... ]     --可选异常处理部分
10 END [trigger_name];    

Examples:

-- an after statement level trigger

CREATE OR REPLACE TRIGGER statement_trigger
AFTER INSERT ON to_table
BEGIN
  DBMS_OUTPUT.PUT_LINE('After Insert Statement Level');
END;
/
/*-- an after row level trigger */
CREATE OR REPLACE TRIGGER row_trigger
AFTER INSERT ON to_table
FOR EACH ROW
BEGIN
  DBMS_OUTPUT.PUT_LINE('After Insert Row Level');
END;
/

-- a before statement level trigger
CREATE OR REPLACE TRIGGER before_statement_trigger
BEFORE INSERT ON to_table
BEGIN
  DBMS_OUTPUT.PUT_LINE('Before Insert Statement Level');
END;
/

-- a before row level trigger
CREATE OR REPLACE TRIGGER before_row_trigger
BEFORE INSERT ON to_table
FOR EACH ROW
BEGIN
  DBMS_OUTPUT.PUT_LINE('Before Insert Row Level');
END;
/

-- after insert statement
CREATE OR REPLACE TRIGGER after_insert_statement
AFTER INSERT ON to_table
BEGIN
  DBMS_OUTPUT.PUT_LINE('After Insert Statement');
END;
/

-- after update statement
CREATE OR REPLACE TRIGGER after_update_statement
AFTER UPDATE ON to_table
BEGIN
  DBMS_OUTPUT.PUT_LINE('After Update Statement');
END;
/

-- after delete statement
CREATE OR REPLACE TRIGGER after_delete_statement
AFTER DELETE ON to_table
BEGIN
  DBMS_OUTPUT.PUT_LINE('After Delete Statement');
END;
/

2.1、使用WHEN子句

例如使用WHEN子句确保只有把薪水修改成不同的值时触发器代码才会执行:

CREATE OR REPLACE TRIGGER check_raise
   AFTER UPDATE OF salary
   ON employees
   FOR EACH ROW
   WHEN (   (old.salary != new.salary)
         OR (old.salary IS NULL AND new.salary IS NOT NULL)
         OR (old.salary IS NOT NULL AND new.salary IS NULL))
BEGIN
   NULL;
END;
/

WHEN子句使用注意事项:

a.要把整个判断逻辑表达式括起来()

b.不要在OLD和NEW之前加上”:”

c.使用WHEN子句时只能使用SQL内置函数;

2.2、使用NEW和OLD伪记录

CREATE OR REPLACE TRIGGER bef_ins_ceo_comp
   BEFORE INSERT
   ON ceo_compensation
   FOR EACH ROW
DECLARE
   PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
   INSERT INTO ceo_comp_history
       VALUES (
                  :new.name
                , :old.compensation
                , :new.compensation
                , 'AFTER INSERT'
                , SYSDATE
              );

   COMMIT;
END;
/

本文链接


    
[3]Oracle编程入门经典 第8章 索引
    来源:    发布时间: 2013-10-29

目录

8.1        索引工作方式... 1

8.2        Oracle中的索引... 1

8.3        索引什么时候有用... 4

8.4        索引开销... 7

8.4.1         插入行怎样影响索引... 7

8.4.2         更新和删除行如何影响索引... 13

8.4.3         DML和索引... 18

8.5        联接... 18

8.5.1         B树索引的键压缩... 19

8.5.2         索引的跳跃搜索... 20

8.6        索引和约束... 25

8.7        反转键索引... 27

8.8        基于函数的索引... 29

8.9        位图索引... 32

8.10          位图联接索引... 35

8.11      小结... 36

正确地使用索引可以将缓慢而顽固的应用调整为响应迅速而产生率高的业务工具。遗憾的是,相反的情况也会发生。在应用中使用没有经过仔细考虑的不恰当的索引,可以将应用调整为对任何人都没有太多用处的行动缓慢的庞然大物。判断索引是否合适以及怎样在适当的时候恰当地建立它,是非常需要技巧的工作——这就是本章将要帮助用户获得的技巧。

  • 什么是索引
  • Oracle中的索引
  • 了解索引价值和开销
  • 索引多个列,键压缩、跳跃搜索、反转键索引
  • 一些特别的索引
  • 基于函数的索引
  • 位图和位图连接索引

8.1   索引工作方式

当用户急于在本书中找到一些有关Oracle特定内容的信息时,可以使用2种方法。用户可以或多或少地按照次序翻阅各页,也许可以碰到正确的主题。或者,如果用户有一些常识的话,也可以使用本书中由印刷商提供的索引。当然,索引本身实际上不会告诉用户任何有关主题的内容,但是它可以为用户提供主题标题以及可以在书中的主体部分找到有关主题完整细节的页面引用。

采用这种方式,利用索引定位特定信息通常要比顺序翻阅各页快得多。

8.2   Oracle中的索引

存储在常规表中的行没有采用特定的次序存储,因此可以满足关系数据库理论的根本原则。当第一次插入行的时候,用户不会控制Oracle选择控制它们的物理位置。这意味着从表中获取特定的行需要Oracle顺序扫描所有可能的行,直到遇到正确的行为止。即使Oracle十分幸运,非常早地找到了与搜索条件相匹配的行,它也只能够在到达了表的逻辑末尾之后才可以停止搜索。这是因为尽管它找到了匹配行,但是这也不意味着这是唯一匹配。

这样的搜索信息方式称为全表搜索(full table scan)。

然而,如果Oracle知道在表的一部分(或者多个部分)上有索引,那么搜索就不必按照顺序,或者实际没有效率的方式进行。一个简单的示例帮助解释Oracle处理这种情况的方式。

考虑表8-1.

表8-1 简单示例表

EMPNO

NAME

DEPT

SAL

Etc…

70

Bob

10

450

10

Frank

10

550

30

Ed

30

575

20

Adam

20

345

40

David

10

550

60

Graham

30

625

50

Charles

20

330

在这里,我们可以看到存储在表中的雇员没有特定的次序。假如我们希望找到Frank的薪金细节。在没有索引的情况下,我们就必须搜索所有7行,然后进行处理,因为即使我们在第2行中找到了Frank,也不能够保证在表中只有唯一的Frank。只有当我们到达了表的高水平标记,通知我们不再有其它的行时,我们才能够停止搜索。

然而这时,我们能够使用如下的SQL语句:

Create index emp_name_idx
On emp(name);

 

这将建立一个索引(特意命名为EMP_NAME_IDX,以便我们只通过查看它的名称,就可以知道这是一个构建在EMP表的NAME列上的索引),这意味着Oracle将会执行一次全表搜索,获取各个记录的名称字段,并将它们进行升序字母排序。这个排序会在第一个实例的内存执行,但是如果证实没有足够的空间可以容纳整个排序,它们也会交换到临时表空间中。Oracle还会将所获取的各个名字与它所在行的rowd进行关联(rowid是表中行的物理地址,可以告诉我们对象的来源,它所处的文件,以及文件中的特定数据块)。在处理之后,我们就会拥有新的索引段。如图8-1所示。

 

图8-1 索引段图示

出于清晰的考虑,我们已经简化了这个图示,并且确定了与索引有关的专门规则,也就是数据块不能够包含超过4个表项。在现实处理中,用户很明显应该在一个数据块中容纳更多的表项,但是这只是原理。数据块只能够容纳有限数量的表项。

这个索引就是B树索引,我们感兴趣的数据都位于基于索引的所谓叶子结点中。如果在索引中有多个叶子结点,Oracle就会构建指向它们的分支结点(Branch Nodes)。在各个叶子结点中,我们可以看到构建索引的关键数据(key data),以及源表中父行的rowid。

顺便提及,“B树索引”中的B不代表经常被认为的“二进制(binary)“,而是代表“平衡(balanced)”。这种情况下的平衡意味着Oracle可以保证用户在到达叶子结点表项之前,在树的一侧不会比另一侧需要穿越更多的索引层次。Oracle采用这种方式维护的结构,可以确保无论索引表项位于何处,都只需花费相同的I/O就可以获取它。

最后要注意,叶子的结点会在2个方向上彼此相连。搜索多行需要扫描多人叶子结点,它不需要不断访问索引结构的顶部。处理完一个叶子结点之后,它就能够直接移动到下一个结点。

使用这个索引搜索Frank意味着我们必须首先访问分支结点。我们将会从这个结点中发现为Frank提供的表项一定处于第二个叶子结点中(因为它的值比“E”大)。因此,我们必须执行第二次数据块读取,读取第二个叶子结点,在那里我们可以开始搜索它的内容。由于提供了一个字段(包含在索引定义中的字段),所以这个搜索会比搜索主表的表项快很多。当我们遇到作为叶子结点中第二个表项的Frank的时候,我们还不能够停止搜索(因为可能还有其它的Frank)。然而,只要我们遇到了“不是Frank”的表项,我们就可以知道(因为具有次序的排序)在索引中没有其它的Franks。所以,在发现实际只有一个Frank之后,我们就可以读取它的rowid,并且执行最后的数据块读取(在这个例子中,要从文件12中读取数据块24),从实际的表中获取他的薪金细节。

到目前为止

    
最新技术文章:
▪current online redo log缺失后的恢复
▪ORA-600 2662错误解决实例
▪ORA-00600 2662错误解决方法
▪Oracle Hidden Parameter:_allow_resetlogs_corruption
▪Oracle诊断事件列表
▪Oracle 隐含参数 _disable_logging 详解
▪ORA-00600 [2662]错误解决过程
▪Oracle里常见的执行计划
▪Oracle里另外一些典型的执行计划
▪Oracle服务器自动备份
▪Oracle固定SQL的执行计划(一)---SQL Profile
▪Oracle固定SQL的执行计划(二)---SPM
▪同一环境下新建Standby RAC库
▪Oracle快速克隆安装
▪Oracle单实例启动多个实例
▪Oracle的PLSQL别名中文出现乱码解决方法
▪ORA-00379: no free buffers available in buffer pool DEFAULT ...
▪RMAN-06023: no backup or copy of datafile 16 found to restor...
▪RMAN还原数据库报错问题解决案例
▪OEL6.8_X86平台部署Oracle 10gR2检测失败问题
▪Oracle 性能优化建议
▪Oracle SQL语句优化心得
▪Oracle慢SQL监控脚本实现
▪Oracle dblink 查询 tns:无法解析指定的连接标识...
▪Red Hat Enterprise Linux 6使用udev配置Oracle ASM总结...
▪Linux6.6及以上版本配置Oracle ASM共享储存-UDEV
▪Oracle 12C 开启数据库归档模式
▪Solairs系统中配置Oracle 12c 开机启动
▪重建DBMS_STATS解决ORA-31626 ORA-21633以及ORA-04063 ORA...
▪Oracle ASMM 与AMM之间相互切换
 


站内导航:


特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

©2012-2021,,E-mail:www_#163.com(请将#改为@)

浙ICP备11055608号-3