22 Triggers
001 |
This chapter discusses triggers, which are procedures stored in PL/SQL
or Java that run (fire) implicitly whenever a table or view is modified
or when some user actions or database system actions occur. |
本章讨论触发器[trigger]。触发器是由 PL/SQL 或 Java 编写的过程[procedure],当表或视图被修改或发生用户操作[user action]或数据库系统操作[database system
action]时被触发运行[fire]。 |
||||||||||||||||||||
002 | This chapter contains the following topics: | 本章包含以下主题: | ||||||||||||||||||||
003 |
Introduction to Triggers |
22.1 触发器简介 |
||||||||||||||||||||
004 |
You can write triggers that fire whenever one of the following
operations occurs:
|
用户可以设定当以下操作发生时,触发器[trigger]被触发运行:
|
||||||||||||||||||||
005 |
Triggers are similar to stored procedures. A trigger stored in the
database can include SQL and PL/SQL or Java statements to run as a unit
and can invoke stored procedures. However, procedures and triggers
differ in the way that they are invoked. A procedure is explicitly run
by a user, application, or trigger. Triggers are implicitly fired by
Oracle when a triggering event occurs, no matter which user is connected
or which application is being used. |
触发器与存储过程[stored procedure]类似。数据库触发器内可以包含 Java 语句,或 SQL 语句及 PL/SQL
结构,也可以调用其他存储过程。触发器与存储过程的区别在于她们的调用方式不同。存储过程是由用户,应用程序或触发器显式地调用的。而触发器是在触发事件[triggering
event]发生时由 Oracle 隐式地触发的,触发器的运行与连接到数据库的用户及用户使用的是何种应用程序无关。 |
||||||||||||||||||||
006 |
Figure 22-1 shows a database
application with some SQL statements that implicitly fire several
triggers stored in the database. Notice that the database stores
triggers separately from their associated tables. |
图 22-1 展示了数据库应用程序中的 SQL
语句能够隐式地触发数据库内存储的触发器。注意,在数据库中触发器与其相关表的存储位置是不同的。 |
||||||||||||||||||||
007 |
Figure 22-1 Triggers |
图 22-1 触发器 |
||||||||||||||||||||
008 | ||||||||||||||||||||||
009 |
Figure 22-1 is described in the text preceding the image. |
图 22-1 将在下文中说明。 |
||||||||||||||||||||
010 |
A trigger can also call out to a C procedure, which is useful for
computationally intensive operations. |
触发器可以调用外部的 C 语言过程,从而保证计算密集型操作[computationally intensive operation]的执行效率。 |
||||||||||||||||||||
011 |
The events that fire a trigger include the following:
|
能够导致触发器被调用的事件包括:
|
||||||||||||||||||||
012 |
Note: |
提示: |
||||||||||||||||||||
013 |
|
另见:
|
||||||||||||||||||||
014 |
How Triggers Are Used |
22.1.1 如何运用触发器 |
||||||||||||||||||||
015 |
Triggers supplement the standard capabilities of Oracle to provide a
highly customized database management system. For example, a trigger can
restrict DML operations against a table to those issued during regular
business hours. You can also use triggers to:
|
触发器[trigger]是 Oracle 数据库提供的标准功能,用户可以通过触发器实现高度自定义的[highly
customized]数据库管理系统。例如,用户可以使用触发器阻止在正常工作时间对指定的表执行 DML 操作。用户还可以使用触发器完成以下工作:
|
||||||||||||||||||||
016 |
See Also: |
另见: |
||||||||||||||||||||
017 |
Some Cautionary Notes about Triggers |
22.1.1.1 使用触发器的注意事项 |
||||||||||||||||||||
018 |
Although triggers are useful for customizing a database, use them only
when necessary. Excessive use of triggers can result in complex
interdependencies, which can be difficult to maintain in a large
application. For example, when a trigger fires, a SQL statement within
its trigger action potentially can fire other triggers, resulting in
cascading triggers. This can produce unintended effects.
Figure 22-2 illustrates cascading
triggers. |
尽管用户可以通过触发器[trigger]实现自定义的[customized]数据库管理系统,但应在必要时才使用触发器。过度的使用触发器将导致系统内存在过于复杂的依赖性[interdependency],从而使大型应用系统变得难以维护。例如,当一个触发器被触发时,其中的
SQL 语句有可能触发其他触发器,从而引起连锁触发[cascading trigger]。这有可能造成不可预料的效果。图 22-2
是一个连锁触发的示例。 |
||||||||||||||||||||
019 |
Figure 22-2 Cascading
Triggers |
图 22-2 连锁触发 |
||||||||||||||||||||
020 | ||||||||||||||||||||||
021 |
Figure 22-2 shows cascading triggers. One SQL statement fires the UPDATE_T1 trigger, which fires the INSERT_T2 trigger, and so on. |
图 22-2 是一个连锁触发的示例。首先,SQL 语句触发了触发器 UPDATE_T1,进而导致触发器 INSERT_T2 被触发。 |
||||||||||||||||||||
022 |
Triggers Compared with Declarative Integrity Constraints |
22.1.1.2 使用触发器与声明完整性约束的比较 |
||||||||||||||||||||
023 |
You can use both triggers and integrity constraints to define and
enforce any type of integrity rule. However, Oracle strongly recommends
that you use triggers to constrain data input only in the following
situations:
|
用户可以使用触发器[trigger]或完整性约束[integrity
constraint]来定义并强制实现各类完整性约束规则[integrity rule]。但是,Oracle
强烈建议用户只在以下情况使用触发器来约束数据输入:
|
||||||||||||||||||||
024 |
See Also: |
另见: |
||||||||||||||||||||
025 |
Parts of a Trigger |
22.2 触发器的组成部分 |
||||||||||||||||||||
026 |
A trigger has three basic parts:
|
一个触发器[trigger]包含 3 个基本组成部分:
|
||||||||||||||||||||
027 |
Figure 22-3 represents each of
these parts of a trigger and is not meant to show exact syntax. The
sections that follow explain each part of a trigger in greater detail. |
图 22-3
展示了触发器的各个组成部分[图中语法并不完全准确]。以下各节将对各个组成部分进行详细介绍。 |
||||||||||||||||||||
028 |
Figure 22-3 The REORDER
Trigger |
图 22-3 触发器 REORDER |
||||||||||||||||||||
029 | ||||||||||||||||||||||
030 |
Figure 22-3 shows the parts of a REORDER trigger. In the top box is the triggering statement. Under that is the trigger restriction, and under that is the triggered action. |
图 22-3 显示了触发器 REORDER 的各个组成部分。图的最上端是触发语句。其下为触发限制条件。最下为触发操作。 |
||||||||||||||||||||
031 |
The Triggering Event or Statement |
22.2.1 触发事件与触发语句 |
||||||||||||||||||||
032 |
A triggering event or statement is the SQL statement, database event, or
user event that causes a trigger to fire. A triggering event can be one
or more of the following:
|
触发语句[triggering statement]及触发事件[triggering event]指导致触发器被触发的 SQL
语句,及数据库事件[database event]或用户事件[user event]。触发事件及触发语句可以是以下情况:
|
||||||||||||||||||||
033 |
For example, in Figure 22-3, the
triggering statement is: |
例如,在 图 22-3 中触发语句为: |
||||||||||||||||||||
034 |
... UPDATE OF parts_on_hand ON inventory ... |
... UPDATE OF parts_on_hand ON inventory ... |
||||||||||||||||||||
035 |
This statement means that when the parts_on_hand
column of a row in the inventory table is
updated, fire the trigger. When the triggering event is an
UPDATE statement, you can include a column
list to identify which columns must be updated to fire the trigger. You
cannot specify a column list for INSERT and
DELETE statements, because they affect
entire rows of information. |
此语句表示,当 inventory 表内数据行的 parts_on_hand
列被更新时触发器将被触发。如果触发事件是 UPDATE
语句,用户可以在触发器定义中包含一个数据列列表,规定只有在列表中的列被更新时触发器才被触发。用户无法为 INSERT
及
DELETE 语句的触发事件设定数据列列表,因为这两种语句会对整个数据行产生影响。 |
||||||||||||||||||||
036 |
A triggering event can specify multiple SQL statements: |
一个触发事件中可以针对多种 SQL 语句: | ||||||||||||||||||||
037 |
... INSERT OR UPDATE OR DELETE OF inventory ... |
... INSERT OR UPDATE OR DELETE OF inventory ... |
||||||||||||||||||||
038 |
This part means that when an INSERT,
UPDATE, or DELETE
statement is issued against the inventory table, fire the trigger. When
multiple types of SQL statements can fire a trigger, you can use
conditional predicates to detect the type of triggering statement. In
this way, you can create a single trigger that runs different code based
on the type of statement that fires the trigger. |
此语句表示,当用户对 inventory 表执行 INSERT,UPDATE,或
DELETE
语句时,触发器将被触发。当多种类型的 SQL 语句均可以触发某个触发器时,用户可以使用条件谓词[conditional
predicate]来判断触发语句的类型。因此,用户可以在一个触发器内,根据触发语句的类型执行不同的程序代码。 |
||||||||||||||||||||
039 |
Trigger Restriction |
22.2.2 触发限制条件 |
||||||||||||||||||||
040 |
A trigger restriction specifies a Boolean expression that must be
true
for the trigger to fire. The trigger action is not run if the trigger
restriction evaluates to false or
unknown. In the example, the trigger
restriction is: |
触发限制条件[rigger restriction]是一个布尔表达式[Boolean expression],只有在表达式为
true 时触发器才被触发。如果触发限制条件的结果为
false 或 unknown
则触发操作[trigger action]不会被执行。示例中的触发限制条件为: |
||||||||||||||||||||
041 |
new.parts_on_hand < new.reorder_point |
new.parts_on_hand < new.reorder_point |
||||||||||||||||||||
042 |
Consequently, the trigger does not fire unless the number of available
parts is less than a present reorder amount. |
因此,只有在零件库存数量小于重下订单需求数量[reorder amount]时,触发器才被触发。 |
||||||||||||||||||||
043 |
Trigger Action |
22.2.3 触发操作 |
||||||||||||||||||||
044 |
A trigger action is the procedure (PL/SQL block, Java program, or C
callout) that contains the SQL statements and code to be run when the
following events occur:
|
触发操作[trigger action]是包含 SQL 语句及控制代码的过程[包括 PL/SQL 块,Java 程序,C
外部调用],满足以下条件时触发操作会被执行:
|
||||||||||||||||||||
045 |
Like stored procedures, a trigger action can:
|
与存储过程[stored procedure]类似,触发操作具有以下特点:
|
||||||||||||||||||||
046 |
If the triggers are row triggers, the statements in a trigger action
have access to column values of the row being processed by the trigger.
Correlation names provide access to the old and new values for each
column. |
如果触发器为行触发器[row trigger],则触发操作能够访问正在被触发器处理的数据行的各个列值。用户可以按照
Oracle 的命名规则访问各列的旧值[old value]及新值[new value]。 |
||||||||||||||||||||
047 |
Types of Triggers |
22.3 触发器的类型 |
||||||||||||||||||||
048 | This section describes the different types of triggers: | 本节讲述不同类型的触发器: | ||||||||||||||||||||
049 |
Row Triggers and Statement Triggers |
22.3.1 行触发器与语句触发器 |
||||||||||||||||||||
050 |
When you define a trigger, you can specify the number of times the
trigger action is to be run:
|
在定义触发器时[trigger],用户可以设定触发操作[trigger action]的执行次数:
|
||||||||||||||||||||
051 |
Row Triggers |
22.3.1.1 行触发器 |
||||||||||||||||||||
052 |
A row trigger is fired each time the table is affected by the
triggering statement. For example, if an UPDATE
statement updates multiple rows of a table, a row trigger is fired once
for each row affected by the UPDATE statement. If a triggering statement
affects no rows, a row trigger is not run. |
行触发器[row trigger]在数据表每次被触发语句[triggering statement]修改时被触发。例如,UPDATE
语句更新了表内的多行数据,行触发器在此 UPDATE
语句更新每行数据时均被触发一次。如果触发语句没有影响任何数据行,则行触发器不会被触发。 |
||||||||||||||||||||
053 |
Row triggers are useful if the code in the trigger action depends on
data provided by the triggering statement or rows that are affected. For
example, Figure 22-3 illustrates
a row trigger that uses the values of each row affected by the
triggering statement. |
如果触发操作[trigger action]的代码需要依据触发语句及其所修改的数据行来执行,就需要使用行触发器。例如,图 22-3
所示的行触发器,需要依据触发语句所修改的数据行来执行。 |
||||||||||||||||||||
054 |
Statement Triggers |
22.3.1.2 语句触发器 |
||||||||||||||||||||
055 |
A statement trigger is fired once on behalf of the triggering
statement, regardless of the number of rows in the table that the
triggering statement affects, even if no rows are affected. For example,
if a DELETE statement deletes several rows
from a table, a statement-level DELETE
trigger is fired only once. |
语句触发器[statement trigger]在触发语句[triggering
statement]每次执行时被触发一次,无论触发语句影响了数据表内多少行数据(或没有修改任何数据行)。例如,当一条 DELETE
语句删除了数据表内的多行数据时,将触发语句级的 DELETE 触发器执行一次。 |
||||||||||||||||||||
056 |
Statement triggers are useful if the code in the trigger action does not
depend on the data provided by the triggering statement or the rows
affected. For example, use a statement trigger to:
|
如果触发操作[trigger action]的代码不需要依据触发语句及其所修改的数据行来执行,就可以使用语句触发器。例如,可以使用语句触发器:
|
||||||||||||||||||||
057 |
BEFORE and AFTER Triggers |
22.3.2 BEFORE 触发器与 AFTER 触发器 |
||||||||||||||||||||
058 |
When defining a trigger, you can specify the trigger timing—whether
the trigger action is to be run before or after the triggering
statement. BEFORE and
AFTER apply to both statement and row triggers. |
在定义触发器时,用户可以指定触发时机[trigger timing],即设定触发操作[trigger
action]在触发语句[triggering statement]之前或之后执行。BEFORE
及
AFTER 可以应用于语句触发器[statement trigger]及行触发器[row trigger]。 |
||||||||||||||||||||
059 |
BEFORE and AFTER
triggers fired by DML statements can be defined only on tables, not on
views. However, triggers on the base tables of a view are fired if an
INSERT, UPDATE,
or DELETE statement is issued against the
view. BEFORE and
AFTER triggers fired by DDL statements can be defined only on the
database or a schema, not on particular tables. |
由 DML 语句触发的
BEFORE 及 AFTER
触发器只能定义在表上,而不能定义在视图上。但在对视图执行
INSERT,UPDATE,或
DELETE 语句时,相关基表[base table]上的触发器仍会被触发。由 DDL
语句触发的
BEFORE 及 AFTER
触发器只能定义在数据库或方案[schema]上,而不能针对特定表。 |
||||||||||||||||||||
060 |
|
|
||||||||||||||||||||
061 |
BEFORE Triggers |
22.3.2.1 BEFORE 触发器 |
||||||||||||||||||||
062 |
BEFORE triggers run the trigger action
before the triggering statement is run. This type of trigger is commonly
used in the following situations:
|
BEFORE 触发器在触发语句[triggering
statement]运行前执行触发操作[trigger action]。此种触发器可以在以下情况使用:
|
||||||||||||||||||||
063 |
AFTER Triggers |
22.3.2.2 AFTER 触发器 |
||||||||||||||||||||
064 |
AFTER triggers run the trigger action after
the triggering statement is run. |
AFTER 触发器在触发语句[triggering
statement]运行后执行触发操作[trigger action]。 |
||||||||||||||||||||
065 |
Trigger Type Combinations |
22.3.2.3 触发器类型的组合 |
||||||||||||||||||||
066 |
Using the options listed previously, you can create four types of row
and statement triggers:
|
用户可以根据前面讲述的触发器类型选项,创建 4 种行触发器[row trigger]及语句触发器[statement trigger]:
|
||||||||||||||||||||
067 |
You can have multiple triggers of the same type for the same statement
for any given table. For example, you can have two
BEFORE statement triggers for UPDATE
statements on the employees table. Multiple
triggers of the same type permit modular installation of applications
that have triggers on the same tables.
Also, Oracle materialized view
logs use
AFTER row triggers, so you can
design your own
AFTER row trigger in
addition to the Oracle-defined
AFTER row
trigger. |
用户可以为一个数据表创建触发语句及类型(BEFORE
或 AFTER)均相同的触发器。例如,用户可以在 employees
上为 UPDATE
语句创建两个
BEFORE statement 触发器。此特性允许不同的应用程序在同一数据表上创建类型相同的触发器。Oracle
在物化视图日志[materialized view log]中使用
AFTER row
触发器,用户可以在 Oracle 定义的触发器之外定义自己的
AFTER row
触发器。 |
||||||||||||||||||||
068 |
You can create as many triggers of the preceding different types as you
need for each type of DML statement, (INSERT,
UPDATE, or DELETE). |
用户为各种 DML 语句(INSERT,UPDATE,或 DELETE)创建前述各
类型触发器的总数量不受限制。 |
||||||||||||||||||||
069 |
See Also: |
另见: |
||||||||||||||||||||
070 |
INSTEAD OF Triggers |
22.3.3 INSTEAD OF 触发器 |
||||||||||||||||||||
071 |
INSTEAD OF triggers provide a transparent
way of modifying views that cannot be modified directly through DML
statements (INSERT,
UPDATE, and DELETE). These triggers
are called INSTEAD OF triggers because,
unlike other types of triggers, Oracle fires the trigger instead of
executing the triggering statement. |
用户可以使用
INSTEAD OF 触发器透明地修改不能由 DML 语句(INSERT,UPDATE,及 DELETE)直接修改的视图。此类触发器被称为
INSTEAD OF 触发器的原因是 Oracle 只运行触发操作[trigger
action]而不运行触发语句[triggering statement]。 |
||||||||||||||||||||
072 |
You can write normal INSERT,
UPDATE, and DELETE
statements against the view and the INSTEAD OF
trigger is fired to update the underlying tables appropriately.
INSTEAD OF triggers are activated for each
row of the view that gets modified. |
用户可以对视图执行普通的 INSERT,UPDATE,及 DELETE
语句,并定义
INSTEAD OF 触发器修改相关的底层表。视图中每个被修改的数据行都将触发
INSTEAD OF 触发器运行一次。 |
||||||||||||||||||||
073 |
Modify Views |
22.3.3.1 修改视图数据 |
||||||||||||||||||||
074 |
Modifying views can have ambiguous results:
|
修改视图数据对基表[base table]的影响是不确定的:
|
||||||||||||||||||||
075 |
Object views present additional problems. For example, a key use of
object views is to represent master/detail relationships. This
operation inevitably involves joins, but modifying joins is
inherently ambiguous. |
操作对象视图[object view]时还存在额外的问题。例如,对象视图的重要用途是表现主信息/明细信息关系[master/detail
relationship]。此类对象视图中必然包含连接,因此修改此类视图时对基表的影响也是不确定的。 |
||||||||||||||||||||
076 |
As a result of these ambiguities, there are many restrictions on which
views are modifiable. An INSTEAD OF trigger
can be used on object views as well as relational views that are not
otherwise modifiable. |
由于存在不确定性,因此一个视图是否能被修改存在诸多限制。对于不可修改的关系型视图[relational view]及对象视图[object
view]可以使用
INSTEAD OF 触发器进行修改。 |
||||||||||||||||||||
077 |
A view is inherently modifiable if data can be inserted, updated,
or deleted without using INSTEAD OF
triggers and if it conforms to the restrictions listed as follows. Even
if the view is inherently modifiable, you might want to perform
validations on the values being inserted, updated or deleted.
INSTEAD OF triggers can also be used in
this case. Here the trigger code performs the validation on the rows
being modified and if valid, propagate the changes to the underlying
tables. |
如果一个视图满足修改的限制条件(详见下节),可以直接插入,更新,或删除而无需使用
INSTEAD OF 触发器,则称此视图为内在可修改的[inherently modifiable]。
即便视图是内在可修改的,用户可能还需要在插入,更新,或删除前验证相关的数据值。此种需求也可以通过
INSTEAD OF
触发器实现。用户可以在触发器代码中验证将要被修改的数据是否有效,验证正确后才将修改应用到相关的底层表中。 |
||||||||||||||||||||
078 |
INSTEAD OF triggers also enable you to
modify object view instances on the client-side through OCI. To modify
an object materialized by an object view in the client-side object cache
and flush it back to the persistent store, you must specify
INSTEAD OF triggers, unless the object view
is inherently modifiable. However, it is not necessary to define these
triggers for just pinning and reading the view object in the object
cache. |
用户还可以在
INSTEAD OF 触发器中通过 OCI
修改客户端[client-side]的对象视图实例[instance]。如果对象视图不是内在可修改的,则必须使用
INSTEAD OF 触发器修改客户端对象缓存[object
cache]内的视图实例,或对视图实例进行持续存储[persistent
store]。如果只需锁定[pinning]或读取[reading]对象缓存内的对象视图,则无需使用触发器。 |
||||||||||||||||||||
079 |
|
|
||||||||||||||||||||
080 |
Views That Are Not Modifiable |
22.3.3.2 不可修改数据的视图 |
||||||||||||||||||||
081 |
If the view query contains any of the following constructs, the view is
not inherently modifiable and you therefore cannot perform inserts,
updates, or deletes on the view:
|
如果视图查询内包含以下结构,则视图不是内在可修改的[inherently modifiable],用户不能直接对视图执行插入,删除,或更新操作:
|
||||||||||||||||||||
082 |
If a view contains pseudocolumns or expressions, you can only update the
view with an UPDATE statement that does not
refer to any of the pseudocolumns or expressions. |
如果视图查询中包含虚列[pseudocolumn]或表达式[expression],用户只能提交没有引用虚列及表达式的 UPDATE
语句修改视图。 |
||||||||||||||||||||
083 |
See Also: |
另见: |
||||||||||||||||||||
084 |
INSTEAD OF Triggers on Nested Tables |
22.3.3.3 嵌套表上的 INSTEAD OF 触发器 |
||||||||||||||||||||
085 |
You cannot modify the elements of a nested table column in a view
directly with the
TABLE clause. However,
you can do so by defining an
INSTEAD OF
trigger on the nested table column of the view. The triggers on the
nested tables fire if a nested table element is updated, inserted, or
deleted and handle the actual modifications to the underlying tables. |
用户不能直接使用 TABLE 子句修改视图中嵌套表列[nested table
column]内的元素[element]。但此需求可以通过在嵌套表上定义
INSTEAD OF
触发器来实现。如果插入,更新或删除了视图内的嵌套表元素,嵌套表的触发器将被触发,对嵌套表执行实际的修改。 |
||||||||||||||||||||
086 |
|
|
||||||||||||||||||||
087 |
Triggers on System Events and User Events |
22.3.4 系统事件触发器与用户事件触发器 |
||||||||||||||||||||
088 |
You can use triggers to publish information about database events to
subscribers. Applications can subscribe to database events just as they
subscribe to messages from other applications. These database events can
include:
|
用户可以使用触发器[trigger]向订阅者[subscriber]发布[publish]数据库事件[database
event]信息。应用程序可以订阅数据库事件,这与订阅其他应用程序发布的消息类似。可供订阅的数据库事件包括:
|
||||||||||||||||||||
089 |
Triggers on system events can be defined at the database level or schema
level. The
DBMS_AQ package is one example
of using database triggers to perform certain actions. For example, a
database shutdown trigger is defined at the database level: |
针对数据库事件的触发器可以定义在数据库级[database level]或方案级[schema level]。常见的例子是在触发器中调用 DBMS_AQ 包执行特定操作。如下所示,在数据库级定义了数据库关闭触发器: | ||||||||||||||||||||
090 |
CREATE TRIGGER register_shutdown |
CREATE TRIGGER register_shutdown |
||||||||||||||||||||
091 |
Triggers on DDL statements or logon/logoff events can also be defined at
the database level or schema level. Triggers on DML statements can be
defined on a table or view. A trigger defined at the database level
fires for all users, and a trigger defined at the schema or table level
fires only when the triggering event involves that schema or table. |
DDL 语句触发器及登录/退出触发器也可以定义于数据库级或方案级。而 DML
语句触发器只能定义在表或视图上。定义于数据库级的触发器可以被所有用户触发,而定义于方案级或表级的触发器只有在方案或表被包含于触发事件[triggering
event]时才得到触发。 |
||||||||||||||||||||
092 |
Event Publication |
22.3.4.1 事件发布 |
||||||||||||||||||||
093 |
Event publication uses the publish-subscribe mechanism of Oracle Streams
Advanced Queuing. A queue serves as a message repository for
subjects of interest to various subscribers. Triggers use the
DBMS_AQ package to enqueue a message when
specific system or user events occur. |
事件发布[event publication]采用的是 Oracle 数据流高级队列[Streams Advanced Queuing]的发布-订阅机制[publish-subscribe mechanism]。队列[queue]如同一个消息资料库[message
repository],其中存储了订阅者[subscriber]感兴趣的信息。触发器使用
DBMS_AQ 包将指定的系统事件或用户事件加入队列。 |
||||||||||||||||||||
094 |
|
|
||||||||||||||||||||
095 |
Event Attributes |
22.3.4.2 事件属性 |
||||||||||||||||||||
096 |
Each event allows the use of attributes within the trigger text. For
example, the database startup and shutdown triggers have attributes for
the instance number and the database name, and the logon and logoff
triggers have attributes for the user name.
You can specify a function
with the same name as an attribute when you create a trigger if you want
to publish that attribute when the event occurs. The attribute's value
is then passed to the function or payload when the trigger fires. For
triggers on DML statements, the
:OLD column
values pass the attribute's value to the
:NEW
column value. |
在触发器代码内可以使用事件属性[event
attribute]。例如数据库启动/关闭[startup/shutdown]触发器可以获得实例编号及数据库名等属性,用户登录/退出[logon/logoff]触发器可以获得用户名等属性。开发者在创建触发器时可以创建与事件属性同名的函数,以便在事件发生时发布此属性。当触发器被触发时事件属性值将被传递给相应的函数。对于
DML 语句触发器,:OLD
列值能够把属性值传递给
:NEW
列值。 |
||||||||||||||||||||
097 |
System Events |
22.3.4.3 系统事件 |
||||||||||||||||||||
098 |
System events that can fire triggers are related to instance startup and
shutdown and error messages. Triggers created on startup and shutdown
events have to be associated with the database. Triggers created on
error events can be associated with the database or with a schema.
|
能够引发触发器执行的系统事件[system event]主要包括实例启动[startup]与关闭[shutdown],及错误消息[error
message]。启动与关闭触发器只能定义于数据库级[database level]。而错误事件[error
event]触发器可以定义于数据库级或方案级[schema level]。
|
||||||||||||||||||||
099 |
User Events |
22.3.4.4 用户事件 |
||||||||||||||||||||
100 |
User events that can fire triggers are related to user logon and logoff,
DDL statements, and DML statements. |
用户登录/退出[logon/logoff],DDL 语句,及 DML 语句等用户事件[user event]能够引发触发器。 |
||||||||||||||||||||
101 |
Triggers on LOGON and LOGOFF Events |
22.3.4.4.1 登录及退出事件的触发器 |
||||||||||||||||||||
102 |
LOGON and LOGOFF
triggers can be associated with the database or with a schema. Their
attributes include the system event and user name,
and they can specify
simple conditions on
USERID and
USERNAME.
|
LOGON 与 LOGOFF
触发器可以定义在数据库或方案[schema]上。此类触发器可使用的属性包括:系统事件[system event]及用户名[user name]。此类触发器中可以使用
USERID
及
USERNAME
函数定义简单条件。
|
||||||||||||||||||||
103 |
Triggers on DDL Statements |
22.3.4.4.2 DDL 语句触发器 |
||||||||||||||||||||
104 |
DDL triggers can be associated with the database or with a schema. Their
attributes include the system event, the type of schema object, and its
name. They can specify simple conditions on the type and name of the
schema object, as well as functions like USERID
and USERNAME. DDL triggers include the
following types of triggers:
|
DDL 触发器可以定义在数据库或方案[schema]上。此类触发器可使用的属性包括:系统事件[system
event],方案对象类型及名称。此类触发器中可以使用方案对象类型及名称,或 USERID
及
USERNAME 函数来定义简单的条件。DDL 触发器包括以下类型:
|
||||||||||||||||||||
105 |
Triggers on DML Statements |
22.3.4.4.3 DML 语句触发器 |
||||||||||||||||||||
106 |
DML triggers for event publication are associated with a table. They can
be either BEFORE or
AFTER triggers that fire for each row on which the specified DML
operation occurs. You cannot use
INSTEAD OF
triggers on views to publish events related to DML statements—instead,
you can publish events using
BEFORE or
AFTER triggers for the
DML operations on a
view's underlying tables that are caused by
INSTEAD OF triggers. |
用于事件发布[event publication]的 DML 触发器针对数据库表。此类触发器可以是 BEFORE
或
AFTER 触发器,当指定的 DML 操作发生时,语句所影响的每行数据都将引发触发器执行。在
Oracle 中无法通过在视图上定义
INSTEAD OF
触发器来发布与视图相关的 DML 事件,要实现此类需求,用户需要在视图的底层表上定义
BEFORE
或
AFTER
触发器来发布事件。 |
||||||||||||||||||||
107 |
The attributes of DML triggers for event publication include the system
event and the columns defined by the user in the
SELECT list. They can specify simple conditions on the type and
name of the schema object, as well as functions (such as
UID, USER,
USERENV, and SYSDATE),
pseudocolumns, and columns. The columns can be prefixed by
:OLD and :NEW
for old and new values. Triggers on DML statements include the following
triggers:
|
用于事件发布的 DML 触发器可使用的事件属性包括:系统事件[system event],及定义在
SELECT 列表中的列值。此类触发器中可以使用方案对象类型及名称,函数(例如
UID,USER,USERENV,或 SYSDATE
等),虚列[pseudocolumn]或列值来定义简单的条件。通过前缀
:OLD 及 :NEW
可以引用列的旧值及新值。DML 触发器包括以下类型:
|
||||||||||||||||||||
108 |
|
|
||||||||||||||||||||
109 |
Trigger Execution |
22.4 触发器执行 |
||||||||||||||||||||
110 |
A trigger is in either of two distinct modes: |
一个触发器之可能处于以下两种状态: |
||||||||||||||||||||
111 |
|
|
||||||||||||||||||||
112 |
For enabled triggers, Oracle automatically performs the following
actions:
|
对于处在启用状态下的触发器,Oracle 将自动地执行以下操作:
|
||||||||||||||||||||
113 |
The Execution Model for Triggers and Integrity Constraint Checking |
22.4.1 触发器及完整性约束检查的执行模式 |
||||||||||||||||||||
114 |
A single SQL statement can potentially fire up to four types of
triggers:
|
一个 SQL 语句可能引发以下四类触发器:
|
||||||||||||||||||||
115 |
A triggering statement or a statement within a trigger can cause one or
more integrity constraints to be checked. Also, triggers can contain
statements that cause other triggers to fire (cascading triggers). |
触发语句[triggering statement]及触发器内的语句可能会导致一个或多个完整性检查[integrity constraint
checking]操作。同样,触发器内的语句还可能引发其他触发器(连锁触发[cascading trigger])。 |
||||||||||||||||||||
116 |
Oracle uses the following execution model to maintain the proper firing
sequence of multiple triggers and constraint checking:
|
Oracle 执行各类触发器及相关完整性约束检查的模式如下,此执行模式[execution
model]确保了各类触发器及相关完整性约束检查的正确执行顺序:
|
||||||||||||||||||||
117 |
The definition of the execution model is recursive. For example, a given
SQL statement can cause a BEFORE row
trigger to be fired and an integrity constraint to be checked. That
BEFORE row trigger, in turn, might perform
an update that causes an integrity constraint to be checked and an
AFTER statement trigger to be fired. The
AFTER statement trigger causes an integrity
constraint to be checked. In this case, the execution model runs the
steps recursively, as follows: |
上述执行模式是可递归的[recursive]。例如,现有一 SQL 语句,能够引发一个
BEFORE row 触发器及一个完整性约束检查。其引发的
BEFORE row 触发器将执行一个更新操作,此更新操作可能会引发一个
AFTER statement 触发器及第二个完整性约束检查。而
AFTER statement
触发器又将引起第三个完整性约束检查。此示例体现了执行模式的递归性,如下所述: |
||||||||||||||||||||
118 |
Original SQL statement issued.
|
首先,初始的 SQL 语句被提交:
|
||||||||||||||||||||
119 |
There are two exceptions to this recursion:
|
递归的执行模式有以下两个特例:
|
||||||||||||||||||||
120 |
An important property of the execution model is that all actions and
checks done as a result of a SQL statement must succeed. If an exception
is raised within a trigger, and the exception is not explicitly handled,
all actions performed as a result of the original SQL statement,
including the actions performed by fired triggers, are rolled back.
Thus, integrity constraints cannot be compromised by triggers.
The
execution model takes into account integrity constraints and disallows
triggers that violate declarative integrity constraints. |
触发器执行模式的一个重要特性是:触发语句引起的所有触发操作及完整性检查必须全部成功执行。如果某个触发操作中出现异常[exception],且此异常没有被显式地处理,那么触发语句执行的所有操作及相关触发器执行的所有操作都会被回滚[roll
back]。需要注意,触发操作也不能违反完整性约束。完整性约束在触发器执行模式中同样有效,因此违反完整性约束的触发操作无法成功执行。 |
||||||||||||||||||||
121 |
For example, in the previously outlined scenario, suppose that the
integrity constraint is violated. As a result of this violation, all
changes made by the SQL statement, the fired
BEFORE row trigger, and the fired AFTER
statement trigger are rolled back. |
例如,在前面所述的示例中,如果出现了违反完整性约束的操作结果,初始 SQL 语句,BEFORE row
触发器,及 AFTER
statement 触发器所做的所有修改都会被回滚。 |
||||||||||||||||||||
122 |
Note: |
提示: |
||||||||||||||||||||
123 |
Data Access for Triggers |
22.4.2 触发器的数据访问 |
||||||||||||||||||||
124 |
When a trigger is fired, the tables referenced in the trigger action
might be currently undergoing changes by SQL statements in other users'
transactions. In all cases, the SQL statements run within triggers
follow the common rules used for standalone SQL statements. In
particular, if an uncommitted transaction has modified values that a
trigger being fired either needs to read (query) or write (update), then
the SQL statements in the body of the trigger being fired use the
following guidelines:
|
当触发器被触发执行时,触发操作[trigger action]所引用的表可能在同时被其他用户事务的 SQL 语句修改。无论何种触发器,其中的
SQL 语句与普通 SQL 语句遵循完全相同的并发访问规则。例如,如果触发操作需要读(查询)或写(更新)被未提交事务[uncommitted
transaction]修改的数据时,那么触发操作内的 SQL 语句遵循以下规则:
|
||||||||||||||||||||
125 |
Storage of PL/SQL Triggers |
22.4.3 PL/SQL 触发器的存储 |
||||||||||||||||||||
126 |
Oracle stores PL/SQL triggers in compiled form, just like stored
procedures. When a CREATE TRIGGER statement
commits, the compiled PL/SQL code, called P code (for pseudocode), is
stored in the database and the source code of the trigger is flushed
from the shared pool. |
Oracle 存储 PL/SQL 触发器编译后的形式,这同其他存储过程的存储方式相同。当用户提交 CREATE TRIGGER
语句时,编译后的 PL/SQL 代码(这种代码被称为 P code,即 pseudocode)会被存储到数据库中,而触发器的源代码[source
code]将被从共享池[shared pool]中清除。 |
||||||||||||||||||||
127 |
See Also: |
另见: |
||||||||||||||||||||
128 |
Execution of Triggers |
22.4.4 触发器的运行 |
||||||||||||||||||||
129 |
Oracle runs a trigger internally using the same steps used for procedure
execution. The only subtle difference is that a user has the right to
fire a trigger if he or she has the privilege to run the triggering
statement. Other than this, triggers are validated and run the same way
as stored procedures. |
Oracle 执行触发操作的步骤与执行普通过程的步骤相同。但二者间存在一个微小区别,只要有权限执行触发语句[triggering
statement]的用户就有权限引发触发器执行。除此之外,触发器的验证[validate]与运行[run]均与存储过程相同。 |
||||||||||||||||||||
130 |
See Also: |
另见: |
||||||||||||||||||||
131 |
Dependency Maintenance for Triggers |
22.4.5 触发器依赖性的维护 |
||||||||||||||||||||
132 |
Like procedures, triggers depend on referenced objects. Oracle
automatically manages the dependencies of a trigger on the schema
objects referenced in its trigger action. The dependency issues for
triggers are the same as those for stored procedures. Triggers are
treated like stored procedures. They are inserted into the data
dictionary. |
与存储过程类似,触发器也依赖于引用对象[referenced object]。Oracle
能够自动地管理触发器及其触发操作所引用方案对象间的依赖关系。触发器所面对的依赖性问题与存储过程的相同。Oracle
管理触发器对象的方式也与存储过程相同。触发器对象的定义保存于数据字典中。 |
||||||||||||||||||||
133 |
See Also: |
另见: |
[098] failover [098] switchover |
[015] derived column value [015] synchronous table replicates [015] subscribing applications [026] trigger restriction [088] role transitions [119] mutating error |
[046] Correlation names provide access to
the old and new values for each column. [056] Make a complex security check on the current time or user [074] Updating a column in a view that involves joins might change the semantics of other columns that are not projected by the view. [075] Object views present additional problems. For example, a key use of object views is to represent master/detail relationships. This operation inevitably involves joins, but modifying joins is inherently ambiguous. [089] The DBMS_AQ package is one example of using database triggers to perform certain actions.| [106] You cannot use INSTEAD OF triggers on views to publish events related to DML statements—instead, you can publish events using BEFORE or AFTER triggers for the DML operations on a view's underlying tables that are caused by INSTEAD OF triggers. [112] Oracle performs integrity constraint checking at a set point in time with respect to the different types of triggers and guarantees that triggers cannot compromise integrity constraints. [119] When a triggering statement modifies one table in a referential constraint (either the primary key or foreign key table), and a triggered statement modifies the other, only the triggering statement will check the integrity constraint. This allows row triggers to enhance referential integrity. [119] Statement triggers fired due to DELETE CASCADE and DELETE SET NULL are fired before and after the user DELETE statement, not before and after the individual enforcement statements. This prevents those statement triggers from encountering mutating errors. [120] The execution model takes into account integrity constraints and disallows triggers that violate declarative integrity constraints. |
[013] SQL, PL/SQL, and Java [079] Object Datatypes and Object Views |
1、如果是行触发器,且约束是 deferred,触发器何时被触发?事务提交时?触发器执行时机和约束检查有关么?After 行触发器需要等待
deferred 约束检查后再触发么? [065-066] 2、不明白? [067] Also, Oracle materialized view logs use AFTER row triggers, so you can design your own AFTER row trigger in addition to the Oracle-defined AFTER row trigger. 3、没接触过? [078] INSTEAD OF triggers also enable you to modify object view instances on the client-side through OCI. To modify an object materialized by an object view in the client-side object cache and flush it back to the persistent store, you must specify INSTEAD OF triggers, unless the object view is inherently modifiable. However, it is not necessary to define these triggers for just pinning and reading the view object in the object cache. 4、没接触过? [085] You cannot modify the elements of a nested table column in a view directly with the TABLE clause. However, you can do so by defining an INSTEAD OF trigger on the nested table column of the view. The triggers on the nested tables fire if a nested table element is updated, inserted, or deleted and handle the actual modifications to the underlying tables. 5、没接触过?最后一句也不理解? [096] You can specify a function with the same name as an attribute when you create a trigger if you want to publish that attribute when the event occurs. The attribute's value is then passed to the function or payload when the trigger fires. For triggers on DML statements, the :OLD column values pass the attribute's value to the :NEW column value. 6、system event 指什么? [098] Their attributes include the system event, instance number, and database name. 7、USERID and USERNAME 是函数么? [103] and they can specify simple conditions on USERID and USERNAME. 8、需要试验。另见 22.4.1 [112] Oracle performs integrity constraint checking at a set point in time with respect to the different types of triggers and guarantees that triggers cannot compromise integrity constraints. 9、理解的对么? [118] Statements of BEFORE row triggers run. |