
CREATE TRIGGER 语句(高级触发器)
FL 500CREATE TRIGGER (高级)语句在架构中定义高级触发器,并在当前服务器上构建触发器包。 每次触发器被激活时,触发器组件都会执行一次或多次。
调用CREATE TRIGGER(高级)
可以通过交互方式发出此语句。 这是一个可执行语句,只有在DYNAMICRULES RUN行为生效时才能动态准备。 更多信息,请参阅授权ID和动态SQL。
CREATE TRIGGER(高级)授权
要在隐式或显式模式中创建新的触发器,下面定义的权限集必须至少包含以下内容之一:
- 模式中的CREATEIN特权
- 系统 DBADM 权限
- SYSCTRL 权限
- SYSADM 权限
- 安装 SYSOPR 权限(当前进程的 SQLID 设置为 SYSINSTL 时)
若要替换触发器而不指定 VERSION 子句,则下面定义的权限集必须至少包含以下内容之一:
- 扳机所有权
- 数据访问权限,以及以下至少一项:
- 在架构中添加DROPIN和CREATEIN特权
- 系统 DBADM 权限
- SYSCTRL 权限
- SYSADM 权限
此外,要创建或替换表的现有触发器,下面定义的权限集必须至少包含以下内容之一: 
- 触发器特权,定义触发器的桌子
- 触发器定义的表格上的ALTER权限
- DBADM 数据库中包含表格的权限
- 系统 DBADM 权限
- SYSCTRL 权限
- SYSADM 权限
- 安装 SYSOPR 权限(当前进程的 SQLID 设置为 SYSINSTL 时)
如果数据库是隐式创建的,则数据库权限必须位于隐式数据库或 DSNDB04 上。
要使用 VERSION 子句添加或替换现有触发器的版本,下面定义的权限集必须至少包含以下一项:
- 扳机所有权
- 数据访问权限和
- 对模式的 ALTERIN 特权
- 系统 DBADM 权限
- SYSCTRL 权限
- SYSADM 权限
以下情况可能需要额外特权:
- 要执行触发器主体,触发器的所有者必须拥有SYSADM权限、DATAACCESS权限或以下各项权限:
- 触发器定义的表或视图的SELECT权限
- 触发操作的 搜索条件中引用的任何表或视图的 SELECT 权限
执行SQL触发器主体语句所需的权限
- 如果指定了SECURED选项,则需要SECADM权限或CREATE_SECURE_OBJECT权限。备注 :如果将“单独安全”子系统参数设置为“否”,则系统管理员权限具有隐含的SECADM权限。
- 如果指定了 WLM ENVIRONMENT FOR DEBUG MODE 子句,则将调用 RACF® 或外部安全产品来检查在 WLM 环境中定义程序所需的权限。 如果WLM环境访问在 RACF 中受到保护,那么发出CREATE语句的用户必须具有所需的权限。 更多信息,请参阅 《WLM环境中创建存储过程的授权管理 》。
- 根据触发器定义的内容,SYSDUMMYx表可能需要额外的授权。 参见 SYSDUMMYx表。
权限设置:
除非进程处于受信任的上下文中,并且指定了 ROLE AS OBJECT OWNER 子句,否则权限集就是进程的 SQL 授权 ID 所拥有的权限。 在这种情况下,特权集是指与流程的主要授权ID关联的角色所拥有的特权,而所有者就是该角色。
CREATE TRIGGER语法(高级)
触发器定义
扳机启动时间
触发器事件
粒度
触发动作
SQL触发器主体
触发SQL语句:
选项列表 :(选项可以任意顺序排列,但每个选项只能出现一次。)
CREATE TRIGGER(高级)描述
OR REPLACE
如果当前服务器上存在触发器定义,则指定替换或更改该定义。 如果当前服务器上不存在触发器定义,那么将忽略此选项。如果未指定 VERSION 关键字,且触发器尚不存在,则使用触发器的初始版本( V1 )创建触发器。
如果未指定 VERSION 关键字,且触发器存在:- 现有触发器不能定义为多个版本,也不能定义为版本标识不是 V1 的单个版本。
- 否则,目前唯一存在的版本是 V1 (或者触发器是一个基本触发器),触发器重新创建如下:
- 在目录中替换定义之前,现有定义实际上已被放弃。
- 任何现有评论将被删除。
- 触发器的定义(包括对象所有者以及目标表或视图名称)可以更改。
- 与触发器定义相关的时间戳被更新。
- 触发器的创建时间已更改,且触发器的激活顺序不再保持不变。
如果指定了 VERSION 关键字,且触发器的指定版本已经存在,那么该版本将在目录中被有效替换,就好像 ALTER TRIGGER 语句是使用 REPLACE VERSION 子句发出的一样。 触发器的所有者和激活顺序不会改变。
替换触发器版本时,以下触发器属性必须与触发器当前活动版本的相应属性相同: 触发器-激活时间、触发器-事件、 表或视图名称以及触发器-粒度。 引用条款的内容可能与触发器的其他版本有所不同。 对于未明确指定的选项,将使用这些选项的系统默认值,即使这些选项是为要替换的触发器版本明确指定的。 指定禁用调试模式的触发器版本则不在此列。 如果为触发器版本指定了 DISABLE DEBUG MODE,则不能使用 REPLACE 子句更改该选项。
如果指定了 VERSION 关键字,而指定的触发器版本不存在,则该版本的定义与 ALTER TRIGGER 语句中的 ADD VERSION 子句相同。 触发器的所有者和激活顺序不会改变。 
添加新版本的触发器时,以下触发器属性必须与当前活动版本触发器的相应属性相同: 触发器-激活时间、触发器-事件、 表或视图名称以及触发器-粒度。 引用条款的内容可能与触发器的其他版本有所不同。 对于未明确指定的选项,将使用这些选项的系统默认值。

- 触发器名称
命名触发器。 名称(包括隐式或显式模式名称)不得标识当前服务器上存在的触发器。 但是,在以下情况下允许指定现有触发器的名称:

- 当指定OR REPLACE子句替换现有触发器时
- 当指定 VERSION 子句以添加或替换现有触发器的版本时

该名称也用于创建触发包;因此,如果未指定 OR REPLACE,该名称也不得标识目录中已描述的包。 模式名称将成为触发器包的集合ID。 虽然触发名称可以指定为普通或分隔标识符,但名称应符合普通标识符的规则。 有关更多信息,请参阅隐式创建的触发器软件包。
如果权限集包含 SYSCTRL 权限,模式名称可以是 "SYSTOOLS"。 否则,除非模式名称为 "SYSADM"、"SYSIBMADM "或 "SYSPROC",否则模式名称不得以 "SYS "开头。
版本 trigger-version-id
指定要定义或替换的触发器版本的版本标识符。 请参阅 SQL中的命名约定 ,了解有关指定触发器版本ID 的信息。 您可以使用带有ADD VERSION子句的ALTER TRIGGER语句或带有OR REPLACE子句的CREATE TRIGGER语句来创建触发器的其他版本。 V1 是默认的版本标识符。 有关触发器版本使用的更多信息,请参阅触发器的版本。
触发激活时间

- NO CASCADE
- 为了与之前的版本和其他产品兼容,不允许使用任何级联。
- BEFORE
- 指定触发器为前触发器。 Db2 在执行触发操作之前,先应用对目标表进行的插入、删除或更新操作所导致的任何更改。 它还规定,触发操作不会激活其他触发器,因为前一个触发器的触发操作不能包含任何更新、REFRESH TABLE或TRUNCATE SQL语句。
当 view-name 也被指定时,不能指定BEFORE。 对于触发器“之前”,必须为每一行指定“FOR EACH ROW”。
- AFTER
- 指定触发器为后触发器。 Db2 在执行触发操作后,对目标表进行插入、删除或更新操作,并应用由此产生的任何更改。 如果同时指定了视图名称 ,则无需指定AFTER。
- INSTEAD OF
- 指定触发器为,而不是触发器。 关联的触发操作将替换对主体视图的操作。 在给定的主题视图中,每种操作类型只允许使用一个“代替”触发器。 Db2 执行触发操作 ,而不是在主题视图中执行插入、更新或删除操作。
如果同时指定了表名 ,则不得指定 INSTEAD OF。 INSTEAD OF触发器不能指定WHEN子句。 INSTEAD OF 触发器必须指定 FOR EACH ROW。

- ON 表名
- 标识“之前”或“之后”触发器定义的主表。 名称必须标识当前服务器上存在的一个基本表。
它不得标识物化查询表、克隆表、临时表、辅助表、别名、同义词、实时统计表、仅加速器表、目录表或目录表。
- ON 视图名称
- 标识触发器定义的“代替”主题视图。 名称必须标识当前服务器上存在的视图。
视图名称不得指定满足以下任何条件的视图:
- 使用“带级联检查”选项(对称视图)定义视图
- 定义对称视图的视图
- 视图引用了使用不同编码方案或CCSID值编码的数据
- 视图有一个ROWID列
- 视图中的列基于以下任何类型的底层列:
- LOB、XML或ROWID列
- 标识列
- 安全标号列
- “行更改时间戳记”列
- “行开始”列
- “行结束”列
- 交易开始ID列
- 视图中有列,列中有字段操作
- 视图的所有基础表都是目录表
- 视图的所有基础表均为全局临时表
- 视图的所有基础表都是克隆表
- 观点取决于其他观点
- REFERENCING
- 指定转换变量的相关名称和转换表的表名。 对于由触发SQL操作(插入、删除或更新)修改的主题表中的行,关联名称用于标识特定行的列。 表标识符用于识别受影响行的完整集合。 在触发器内部无法引用XML类型的过渡变量。 如果引用了转换表的列,则该列的数据类型不能是XML。
通过使用以下指定的相关名称限定列名,触发 SQL 操作影响的每一行都可用于触发操作:
旧行作为相关性名称
指定相关性名称,该名称用于识别在触发 SQL 操作之前的记录中包含值的过渡变量。
新行作为相关性名称
指定相关名称,该名称用于标识包含被触发 SQL 操作和已执行的 before 触发器中的任何赋值语句修改的行中值的过渡变量。
如果同时指定了 "旧 "和 "新",则对过渡变量的引用必须使用相关的关联名称。
触发操作所影响的一组完整行可用作触发操作的过渡表。 指定一个表标识符来引用转换表,如下所示:
- OLD_TABLE AS 表标识符
- 指定临时表的名称,该临时表用于标识在触发SQL操作之前,实际更改之前,完整行集中被修改的行的值。
NEW_TABLE AS 表标识符
指定临时表的名称,该临时表用于标识被触发 SQL 操作和已执行的 before 触发器中的任何赋值语句修改的整套记录中的值。 
一个触发器只能指定一个 OLD 相关名和一个 NEW 相关名。 一个触发器只能指定一个OLD_TABLE和一个NEW_TABLE 表标识符。 所有相关名称和表格标识符必须彼此唯一。
表1 总结了您可以为各种触发类型指定的过渡变量和过渡表的允许组合。 仅当触发事件是删除操作或更新操作时,OLD 关联名 和OLD_TABLE表标识符才有效。 对于删除操作,OLD 关联名称捕获已删除行中列的值,OLD_ TABLE表标识符捕获已删除行集中的值。 对于更新操作,OLD 关联名称捕获更新操作前一行各列的值,OLD_T ABLE表标识符捕获更新操作前一组行的值。
只有当触发事件是插入操作或更新操作时,NEW 相关名称和 NEW_TABLE 表标识符才有效。 对于这两种操作, 新的关联名称捕获插入或更新行中列的值,而新的表标识符捕获插入或更新行集中的值。 对于 BEFORE 触发器,更新行的值包括 BEFORE 触发器触发操作中任何赋值语句的更改。
表 1. 触发器定义中允许的属性组合 详细程度 激活时间 触发 SQL 操作 (triggering SQL operation) 允许过渡变量 1 允许使用转换表1 FOR EACH ROW BEFORE 删除 旧 NONE INSERT 新 NONE UPDATE 旧,新 NONE AFTER 删除 旧 OLD_TABLE INSERT 新 NEW_TABLE UPDATE 旧,新 旧表,新表 INSTEAD OF 删除 旧 OLD_TABLE INSERT 新 NEW_TABLE UPDATE 旧,新 旧表,新表 FOR EACH STATEMENT AFTER 删除 NONE OLD_TABLE INSERT NONE NEW_TABLE UPDATE NONE 旧表,新表 注:- 如果引用了不允许引用的转换表或变量,则返回错误。
具有字符数据类型的转换变量继承源表列的子类型和CCSID。 在触发动作执行期间,过渡变量被视为宿主变量。 因此,可能会发生字符转换。 然而,与宿主变量不同,转换变量可以具有位数据属性,并且位数据永远不会发生字符转换。 如果表中的对应列是位数据,则过渡变量被视为位数据。
您不能修改转换表;转换表是只读的。 虽然转换表不会从主题表中继承任何编辑或验证程序, 但它会继承主题表的编码方案和字段程序。
每个关联名称和每个表标识符的范围是整个触发器定义。
- 粒度
- 每行或每句话
- 指定 Db2 执行触发操作的条件。
- FOR EACH ROW
- 指定 Db2 对触发SQL操作修改的表中的每一行执行触发操作。 如果触发的SQL操作没有修改任何行,则不会执行触发操作。
- FOR EACH STATEMENT
- 指定 Db2 仅对触发操作执行一次触发操作。 即使触发操作不修改或删除任何行,触发操作也会被执行一次。
对于每个语句,不得指定为“之前”或“代替”触发器。
- FOR EACH ROW 或者 FOR EACH STATEMENT
- 指定 Db2 执行触发操作的条件。
- FOR EACH ROW
- 指定 Db2 对触发SQL操作修改的表中的每一行执行触发操作。 如果触发的SQL操作没有修改任何行,则不会执行触发操作。
- FOR EACH STATEMENT
- 指定 Db2 仅对触发操作执行一次触发操作。 即使触发操作不修改或删除任何行,触发操作也会被执行一次。
对于每个语句,不得指定为“之前”或“代替”触发器。
允许调试模式、禁止调试模式或禁用调试模式
指定该版本的触发器能否在调试模式下运行。 默认值由当前调试模式特殊寄存器的值决定。- 允许调试方式
- 指定此版本的触发器可在调试模式下运行。 启用“允许调试模式”时,必须具备WLM环境。 如果您没有指定调试模式的WLM环境, Db2 将使用安装时指定的默认WLM存储过程地址空间。
- 禁用调试方式
- 指定此版本的触发器不能在调试模式下运行。 您可以使用ALTER语句将触发器的初始版本选项更改为ALLOW DEBUG MODE。 当“禁止调试模式”生效时,必须有一个WLM环境可用。 如果您没有指定调试模式的WLM环境, Db2 将使用安装时指定的默认WLM存储过程地址空间。
- 禁用调试方式
- 指定此版本的触发器不能在调试模式下运行。
在创建或更改此版本的触发器以使用“禁用调试模式”后,无法更改此版本的触发器以指定“允许调试模式”或“禁用调试模式”。 要更改此选项,请放下扳机,然后使用所需的选项重新创建。 除了删除并重新创建触发器之外,另一种方法是创建一个使用所需选项的触发器版本,并使其成为活动版本。
当禁用调试模式生效时,调试模式的WLM环境将被忽略。

QUALIFIER 模式名
指定隐式限定符,用于在触发器正文中引用的未限定的对象名称。 有关如何确定该选项的默认值的信息,请参阅未限定的别名、索引、JAR 文件、掩码、权限、序列、表、触发器和视图名称。 
- ASUTIME
- 指定每次调用此版本的触发器可以运行的处理器总时间(以CPU服务单元为单位)。 该值与资源限制规格表的 ASUTIME 列无关。
当您调试触发器时,如果触发器陷入循环,设置限制可能会有所帮助。 有关服务单元的信息,请参阅 z/OS MVS Initialization and Tuning Guide。
- 无限制
- 规定服务单元没有限制。
默认值为“无限制”。
- 极限整数
- CPU服务单元的数量限制为1-2147483647之间的正整数。 如果触发器使用的服务单元数量超过指定值, Db2 将取消触发器。 触发器中并行任务所消耗的CPU周期不计入指定的ASUTIME LIMIT。
用于调试模式的 WLM 环境名称
指定 Db2 在调试触发器时使用的 WLM(工作负载管理器)应用环境。 WLM环境名称是一个SQL标识符。如果您没有指定调试模式的WLM环境, Db2 将使用安装时指定的默认WLM存储过程地址空间。
您必须拥有WLM应用环境的相应权限。
当禁用调试模式时,调试模式下的WLM环境值将被忽略。

当前数据 "是 "或 "当前数据 "否
指定在游标稳定性隔离级别生效时,是否要求只读游标和模糊游标使用数据货币。 当前数据还决定着块获取是否可用于分布式、模糊游标。- 当前数据 是
- 指定只读和模糊游标需要数据货币。 Db2 获取页面或行锁以确保数据更新。 对于分布式、模糊游标,块获取将被忽略。
- 当前数据 无
- 指定只读和模糊游标不需要数据货币。 对于分布式、模糊游标,允许块获取。 如果触发器试图在打开模糊游标后动态准备并执行DELETE WHERE CURRENT OF语句,则不建议使用CURRENT DATA NO。 如果触发器尝试对以下游标使用DELETE WHERE CURRENT OF语句,则会收到错误:
- 正在使用块获取的光标
- 使用并行性查询的游标
- 放置在由此或另一个应用程序进程修改的行上的游标
当前数据编号为默认值。

- CONCURRENT ACCESS RESOLUTION
- 指定处理是否仅使用已提交的数据,还是等待正在更新中的数据的提交或回滚。
- WAIT FOR OUTCOME
- 指定处理将等待正在更新中的数据的提交或回滚。
- USE CURRENTLY COMMITTED
- 指定当遇到正在更新的数据时,处理过程使用当前提交的数据版本。 USE
CURRENTLY COMMITTED 适用于访问通用表空间中定义的表的扫描,这些表具有行级或页级锁定大小。
当读取事务和插入事务之间存在锁争用时, USE CURRENTLY COMMITTED 适用于隔离级别为CS或RS的扫描。 适用的扫描包括针对只读和模糊查询以及可更新游标的意向读取扫描。 USE CURRENTLY COMMITTED 也适用于从UPDATE或DELETE语句的WHERE子句和INSERT语句的子选择中启动的扫描。
当读事务和删除事务之间存在锁争用时, USE CURRENTLY COMMITTED 适用于隔离级别为CS且指定了CURRENT DATA NO的扫描。
动态规则
指定运行时适用于以下动态 SQL 属性的值:- 用于检查授权的授权标识
- 用于不合格对象的限定符
- Db2 用于解析和语义验证动态SQL语句的应用程序编程选项的源文件
在触发器中,DYNAMICRULES还指定动态SQL语句是否可以包含ALTER、CREATE和DROP语句。
除了DYNAMICRULES条款的价值外,触发器的运行时环境还控制着动态SQL语句在运行时的行为。 DYNAMICRULES值和运行环境共同决定了动态SQL属性的值。 该组属性值被称为动态 SQL 语句行为。 可以指定下列值:- 运行
- 指定动态 SQL 语句将使用运行行为进行处理。
默认值为“运行”。
- BIND
- 指定动态 SQL 语句将使用绑定行为进行处理。

应用编码方案
指定触发器正文中静态 SQL 语句中 SQL 变量的默认编码方案。 如果CCSID子句未指定为数据类型的一部分,则该值用于在复合语句中定义SQL变量。- ASCII
- 指定使用服务器的ASCII CCSID对数据进行编码。
- EBCDIC
- 指定使用服务器的EBCDIC CCSID对数据进行编码。
- UNICODE
- 指定使用服务器的Unicode CCSID对数据进行编码。
有关如何确定此选项的默认值的信息,请参阅编码绑定选项。

带解释或不带解释
指定是否提供有关触发器中 SQL 语句执行方式的信息。- 无需解释
- 指定不显示触发器中SQL语句的执行方式。
如果语句嵌入在触发器中,而触发器又使用不带EXPLAIN指定,则可以通过在触发器主体中嵌入SQL语句EXPLAIN来获得该语句的EXPLAIN输出。 否则,EXPLAIN选项适用于触发器主体中所有可解释的SQL语句,以及任何DECLARE CURSOR语句的fullselect部分。
默认值为“无解释”。
- 附带解释
- 指定提供有关触发器中的SQL语句如何执行的信息。 信息被插入到表格所有者中。 PLAN_TABLE。 owner 是触发器所有者的授权ID。 或者,触发器所有者的授权ID可以有一个别名, 例如owner.PLAN_TABLE ,指向基础表PLAN_TABLE。 所有者还必须对该表拥有适当的 SELECT 和 INSERT 权限。 PLAN_TABLE必须有一个基本表,可以有多个别名,表名相同,但结构限定符不同。
它不能是视图或同义词,并且应在处理 CREATE 语句之前就存在。
在所有对 owner.PLAN_TABLE 的插入中,QUERYNO 的值是 Db2 分配的语句编号。如果存在DSN_STATEMNT_TABLE和DSN_FUNCTION_TABLE两个可选表,则WITH EXPLAIN选项也会填充这两个表。 DSN_STATEMNT_TABLE包含SQL语句的处理成本估算。 更多信息,请参阅 《估算 SQL 语句的成本 》。 DSN_FUNCTION_TABLE包含有关函数解析的信息。 更多信息请参阅 《检查 Db2 如何使用 DSN_FUNCTION_TABLE 解析函数 》。
有关 EXPLAIN 语句的更多信息,包括 WITH EXPLAIN 选项填充的表的描述,请参阅 EXPLAIN 语句。

有即时写入功能或无即时写入功能
指定是否立即写入对分组缓冲池相关页面集或分区的更新。 此选项仅适用于数据共享环境。 即时写入子系统参数不影响此选项。 即时写入绑定选项显示了即时写入绑定选项(与该触发选项类似)的隐含层次结构,因为它会影响运行时间。- 无需立即撰写
- 指定执行正常的写入活动。 依赖于组缓冲池的更新页面在提交的第一阶段或之前写入,或者对于已回滚的事务,在中止结束时写入。
默认值为“不立即写入”。
- 立即写
- 指定一旦缓冲区更新完成,立即写入依赖于组缓冲池的更新页面。 即使缓冲区在事务处理前进或回滚期间更新,更新的页面也会立即写入。 立即写入可能会影响性能。

隔离等级 RR、RS、CS 或 UR
指定触发器与其他运行中应用程序的隔离程度。 如需了解隔音等级信息,请参阅 “选择隔音选项 ”。- RR
- 指定可重复读取。
- RS
- 指定读取稳定性。
- CS
- 指定光标稳定性。 CS是默认设置。
- UR
- 指定未承诺的阅读。

OPTHINT 字符串常数
指定是否对包含在触发器正文中的静态 SQL 语句使用查询优化提示。字符串常量是一个长度不超过128字节的字符串,当 Db2 子系统在PLAN_TABLE中搜索行作为输入时使用。 默认值为空字符串,表示 Db2 子系统不对静态SQL语句使用优化提示。
优化提示仅在您的系统启用了优化提示时可用。 请参阅 “准备影响访问路径 ”,了解启用优化提示的相关信息。

SQL 路径
指定 SQL 路径, Db2 用于解析触发器正文中未限定的用户定义类型、函数和存储过程名称。 默认值为 “SYSIBM”、“SYSFUN”、“SYSPROC”、“SYSIBMADM ”和QUALIFIER选项的值。无需明确指定 “SYSIBM”、“SYSFUN”、“SYSPROC”、“SYSIBMADM” 等架构。 如果这些模式中未明确指定任何模式,则会在SQL路径的开头按列出的顺序隐式假设。
Db2 通过以下方式计算长度:取指定的每个模式名称 ,删除其末尾的空白,在其前后添加两个分隔符,并在每个模式名称后添加一个逗号,最后一个除外。 生成的字符串长度不能超过当前模式特殊寄存器的长度。 如果您没有指定 “SYSIBM”、“SYSFUN”、“SYSPROC”、“SYSIBMADM ”模式,它们将不会包含在SQL路径的长度中。 如果SQL路径的总长度超过了CURRENT PATH特殊寄存器的长度, Db2 将返回错误。
有关更多信息,请参阅:
- schema-name
- 标识模式。 Db2 在处理CREATE语句时,不会验证模式是否存在。 同一个模式名称不应在模式名称列表中出现两次以上。
SYSPUBLIC不能指定为SQL路径。
- 系统 PATH
- 指定架构名称 “SYSIBM”、“SYSFUN”、“SYSPROC”、“SYSIBMADM ”。
- SESSION_USER或USER
- 指定SESSION_USER或USER特殊寄存器的值,该值表示一个最多8字节(EBCDIC) 的架构名称。 在处理CREATE语句时,该长度将包含在为SQL PATH选项指定的模式名称列表的总长度中。
如果在模式名称列表中指定 SESSION_USER(或 USER),请不要在 SESSION_USER(或 USER)关键字周围使用分隔符。

发布于
指定何时释放触发器使用的资源:在每个提交点或触发器终止时。- COMMIT
- 指定在每个提交点释放资源。
COMMIT是默认值。
- DEALLOCATE
- 指定资源仅在线程终止时释放。 DEALLOCATE对动态SQL语句没有影响,后者总是使用RELEASE AT COMMIT,但以下情况例外:当您使用RELEASE AT DEALLOCATE子句和WITH KEEP DYNAMIC子句时,且子系统在安装面板 DSNTIP8 上为CACHE DYNAMIC SQL字段安装了值为YES的值,则RELEASE AT DEALLOCATE选项适用于动态SELECT和数据更改语句。
在以下任一事件发生时,为动态陈述而购买的锁将被收回:
- 应用程序进程结束。
- 申请流程会生成一份带有相同声明标识符的PREPARE声明。 (在下一个提交点解锁)。
- 由于语句未被使用,因此从动态语句缓存中移除。 (在下一个提交点解锁。)
- 声明所依赖的对象被删除或更改,或者声明所需的特权被撤销。 (在下一个提交点解锁。)
释放 AT DEALLOCATE 可能会增加软件包或计划的大小,因为附加项目会驻留在软件包或计划中。
更多信息,请参阅选择发布选项。

四舍五入
指定操作 DECFLOAT 数据的四舍五入模式。 默认值来自应用程序编程默认模块中的默认十进制浮点舍入模式。- 圆形天花板
- 指定数字取整为正无穷大。
- 四舍五入
- 指定数字四舍五入为0(截断)。
- 圆地板
- 指定数字舍入为负无穷大。
- Dec_round_half_down
- 指定数字四舍五入取整;如果等距,则向下取整。
- 十进制半双
- 指定数字四舍五入取整;如果等距,则四舍五入取整,使最后一位数字为偶数。
- 十进制半上
- 指定数字四舍五入取整;如果等距,则向上取整。
- 四舍五入
- 指定数字舍入到0以外。

日期格式 ISO、EUR、USA、JIS 或 LOCAL
为以字符串形式表示日期或时间值的结果值指定日期格式。 更多信息请参见日期时间值的字符串表示。默认格式在定义例程的系统安装面板 DSNTIP4 的日期格式字段中指定。 除非您有日期退出程序,否则无法使用“本地”选项。

DECIMAL(15)、DECIMAL(31)、DECIMAL(15, s ) 或 DECIMAL(31, s )
指定十进制算术运算的最大精度。 更多信息请参阅 《算术:两个小数运算数 》。 默认格式在定义例程的系统安装面板 DSNTIPF 的 DECIMAL ARITHMETIC 字段中指定。 如果指定 pp.s 的形式,则 s 必须是 1-9 范围内的数字。s 表示除法所用的最小刻度。
时间格式 ISO、EUR、USA、JIS 或 LOCAL
为以字符串形式表示日期或时间值的结果值指定时间格式。 更多信息请参见日期时间值的字符串表示。默认格式在定义例程的系统安装面板 DSNTIP4 的“时间格式”字段中指定。 除非您有日期退出程序,否则无法使用“本地”选项。

FOR UPDATE CLAUSE OPTIONAL 或 FOR UPDATE CLAUSE REQUIRED
如果游标用于执行定位更新,则指定 DECLARE CURSOR 语句是否需要 FOR UPDATE 子句。- 需要更新条款
- 规定如果游标将用于定位更新,则必须将FOR UPDATE子句作为游标定义的一部分。
默认情况下,需要更新条款。
- 更新条款可选
- 指定在定位更新中使用游标时,无需指定 FOR UPDATE 子句。 触发器主体可以包含定位UPDATE语句,用于更新用户有权限更新的列。

- NOT SECURED 或 SECURED
- 指定触发器是否视为安全触发器。 默认设置是“未锁定”。
- SECURED
- 指定触发器被视为安全触发器。
如果触发器的目标表使用行访问控制或列访问控制,则必须指定SECURED。 如果为视图创建触发器,且视图定义中一个或多个基础表使用行访问控制或列访问控制,则还必须指定SECURED。
- NOT SECURED
- 指定触发器被认为不安全。
对于使用行访问控制或列访问控制的触发器,不能指定NOT SECURED。 如果视图定义中有一个或多个基础表使用行访问控制或列访问控制,则不能为视图创建的触发器指定NOT SECURED。
业务时间敏感
决定静态和动态 SQL 语句中对应用周期时态表的引用是否受 CURRENT TEMPORAL BUSINESS_TIME 特殊寄存器值的影响。- YES
- 对申请期间临时表的引用受当前临时业务时间特殊寄存器的值影响。 缺省值是 YES。
- 否
- 对申请期间临时表的引用不受当前临时业务时间特殊寄存器的值的影响。
更多信息,请参阅当前时间业务时间特别登记册。

SYSTEM_TIME SENSITIVE
决定静态和动态 SQL 语句中对系统周期时态表的引用是否受 CURRENT TEMPORAL SYSTEM_TIME 特殊寄存器值的影响。- YES
- 对系统周期时态表的引用会受CURRENT TEMPORAL SYSTEM_TIME专用寄存器的值影响。 缺省值是 YES。
- 否
- 对系统周期时态表的引用不会受CURRENT TEMPORAL SYSTEM_TIME专用寄存器的值影响。
更多信息,请参阅当前时间系统_时间特殊寄存器。

档案敏感
确定 SQL 语句中对启用存档的表的引用是否受 SYSIBMADM.GET_ARCHIVE 内置全局变量值的影响。- YES
- 对启用存档的表的引用受 SYSIBMADM.GET_ARCHIVE 内置全局变量值的影响。 缺省值是 YES。
- 否
- 对启用存档的表的引用不受 SYSIBMADM.GET_ARCHIVE 内置全局变量值的影响。
相关信息请参阅 GET_ARCHIVE内置全局变量。

APPLCOMPAT Appcompat-level

指定触发器正文中静态 SQL 语句的应用程序兼容级别行为。 默认值为 V12R1M500 ,触发器的 appcompat-level 必须为 V12R1M500 或更高。 更多信息,请参阅 Db2 12 中的 APPLCOMPAT 级别。
更多信息,请参阅 APPLCOMPAT绑定选项和 APPL COMPAT LEVEL字段(APPLCOMPAT子系统参数 )

浓缩语句或浓缩语句中的词汇
指定是否将指定字面常量的动态 SQL 语句作为单独的唯一语句条目缓存到动态语句缓存中,而不是共享缓存中的现有语句。 如果新语句满足共享同一动态语句缓存版本的所有条件,则动态SQL语句可以共享缓存中的现有语句,但新语句指定了一个或多个与缓存语句不同的字面常量。- 集中陈述 OFF
- 指定动态 SQL 语句中指定的文字常量将被缓存为唯一语句条目,前提是它指定了一个或多个与同一动态语句的缓存版本不同的常量。 集中式语句 OFF 是默认的动态语句缓存行为。
- 用文字浓缩语句
- 指定动态 SQL 语句中指定的文字常量将共享同一动态语句的缓存版本,如果新的动态语句满足共享缓存语句的所有条件,并且指定的常量可以代替缓存语句中的常量,则该动态语句也将使用 CONCENTRATE STATEMENTS WITH LITERALS 选项进行准备。

- 触发器事件
- 指定当触发事件应用于主体表或视图时,与触发器关联的触发操作将被执行。
- INSERT
- 指定触发器为插入触发器。 Db2 每当在目标表上进行插入操作时,就会执行触发操作。 但是,如果在任何解释表中定义了插入触发器,并且插入操作是由 Db2 向表中添加一行引起的,则不会执行触发操作。
- 删除
- 指定触发器为删除触发器。 Db2 每当对目标表进行删除操作时,就会执行触发操作。
- UPDATE
- 指定触发器为更新触发器。 Db2 每当主题表有更新操作时,就会执行触发操作。
如果您没有指定列名列表,则对目标表任何列(包括随后通过ALTER TABLE语句添加的列)进行的更新操作都会激活触发操作。
- 列名 ,..
- 您指定的每个列名必须是主题表的列,且在列表中只能出现一次。 对列出的任何一列进行更新操作,即可激活触发操作。
UPDATE OF 列名不能指定为INSTEAD OF触发器。
- 触发动作
- 指定触发器激活时执行的操作。 触发操作由一个或多个SQL语句和一个可选条件组成,该条件用于控制语句是否被执行。
- WHEN (搜索条件 )
- 指定一个条件,其值为真、假或未知。 只有当搜索条件为真时,才会执行触发的SQL语句。 如果省略了WHEN子句,则始终执行关联的SQL语句。
INSTEAD OF触发器不能指定WHEN子句。
- SQL触发器主体
指定触发操作要执行的单个 SQL 控制语句 (包括复合语句)或触发的 SQL 语句。 有关定义 SQL 触发器的更多信息,请参阅 SQL 过程语言 (SQL PL)。
SQL 控制语句
指定 SQL 控制语句,可包括嵌套控制语句和 SQL-Procedure-statement (SQL PL) 语法图中指定的其他 SQL 语句。 可为 SQL-procedure-statement 指定的语句受触发器相关语法说明的限制。
- 触发的 SQL 语句
指定一个SQL语句,该语句是触发器主体中唯一的语句。
.
在 SQL触发器主体中只能指定某些SQL语句。
触发器主体不得包含不受支持的语句。
- 触发器主体中的语句不得引用宿主变量、未定义的转换变量或已声明的临时表。
- 触发器主体中的语句只能引用当前服务器上的表或视图。
触发器主体中的语句只能调用当前服务器上的存储过程或用户定义的函数。 不过,被调用的例程可以访问当前服务器以外的服务器。
触发器正文中的语句不得修改属于 BUSINESS_TIME 期间的列。
- 触发器主体不得直接或间接为包含以下语句之一的程序发出CALL语句:
- COMMIT
- CONNECT
- 释放连接
RELEASE SAVEPOINT
- 回滚(不保存到保存点)
SAVEPOINT
- SET CONNECTION
- 触发器主体不得直接或间接为使用COMMIT ON RETURN选项定义的程序发出CALL语句。
- 如果触发条件是先于触发条件:
触发器主体不得包含 DELETE、INSERT、MERGE、REFRESH TABLE、TRUNCATE、UPDATE 语句或 SELECT FROM 数据更改语句。
触发器主体不得直接或间接调用包含以下语句之一的例程:- ALTER
- COMMENT
- 创建
- DECLARE GLOBAL TEMPORARY TABLE
- 删除
- DROP
- EXCHANGE
- GRANT
- INSERT
- 标签
- LOCK TABLE
- MERGE
- REFRESH TABLE
- RENAME
- REVOKE
- TRUNCATE
- UPDATE

CREATE TRIGGER 语句(或 ALTER TRIGGER 语句)不能包含十六进制图形字符串(GX)常量。
触发的操作可以参考受影响行集中的值。 通过使用过渡变量和过渡表来支持这一操作。
当触发器创建或触发器版本定义时, 触发器中引用的所有表、视图、别名、序列、角色、用户定义的数据类型、用户定义的函数和过程必须在当前服务器上存在。 创建触发器或定义触发器版本时,别名所引用的表或视图也必须存在。
WRAPPED 混淆语句文本
FL 500指定触发器的编码定义。 CREATE TRIGGER 语句可以使用 WRAP 标量函数进行编码。WRAPPED 不能在静态 CREATE 语句中指定。

CREATE TRIGGER(高级)的注意事项
- 车主特权:
- 当定义了“代替”触发器时,相关权限(视图上的插入、更新或删除)将赋予视图的所有者。 车主有权将此特权授予他人。 有关对象所有权的更多信息,请参阅授权、特权、权限、掩码和对象所有权。
- 执行授权:
- 执行触发SQL操作的用户无需权限即可执行 SQL触发器主体。 SQL触发器主体使用触发器所有者的权限执行。
- 启动触发器:
- 只有插入、删除或更新操作才能激活触发器。 触发器的激活可能会导致触发器级联。触发器级联是指一个触发器激活后执行 SQL 语句,从而导致其他触发器或甚至同一触发器再次激活。 触发的操作也可能因原始修改而引起更新,从而导致其他触发器的激活。 触发级联是指,由于一次 插入、删除或更新操作,可能会激活一系列触发器,从而导致数据库发生重大变化。 嵌套触发级联的层级数限制为16。
如果指定或接受 SHRLEVEL NONE 选项作为默认选项,则使用 LOAD 实用程序加载表格不会激活为表格定义的任何触发器。 如果LOAD语句包含SHRLEVEL CHANGE选项,则在用LOAD实用程序加载表时触发器被激活。
- 添加触发器以强制执行约束:
- 在已有行的表格上添加触发器不会导致触发动作被执行。 因此,如果触发器旨在对表中的数据进行约束,则现有行中的数据可能不符合这些约束。
- 多重触发:
- 可以在表格中定义多个具有相同激活时间和触发事件的触发器。 触发器按创建顺序依次激活。 例如,首先创建的触发器首先执行;其次创建的触发器其次执行。
如果使用 OR REPLACE 选项替换现有触发器,创建时间会发生变化,因此可能会影响触发器的执行顺序。
- 过渡变量和过渡表:
- 触发操作可以参考受影响行集中的值。 通过使用过渡变量和过渡表来支持这一操作。
过渡变量与触发器所定义的表中的相应列具有相同的名称和数据类型,并且可以为空。 过渡变量包含受影响行中某一列的值。 转换变量由关联名称限定,该名称用于标识引用的是旧值(更新前)还是新值(更新后)。 在触发器主体的查询条件或 SQL 语句中可以引用过渡变量,前提是在触发器主体之外引用变量时允许使用该变量。 在更新或插入触发器中,可以为新的过渡变量赋值。 更新行的值包括从任何赋值到触发器触发前动作中的过渡变量的变化。
转换表包含受影响行的完整集合:旧值(更新前)或新值(更新后)。 转换表是只读的, 可以在触发器动作之后或代替触发器引用。 转换表的列与触发器所定义的表的相应列具有相同的名称、数据类型和空属性。 转换表使用关联表标识符进行引用,该标识符允许将受影响行的完整集合视为一个表。 在触发器主体的搜索条件或SQL语句中可以引用转换表,前提是在触发器主体之外引用该表是允许的。 此外,转换表可以作为参数传递给用户定义的函数或过程,在转换表的表标识符前指定TABLE关键字。 当调用函数或过程时,会传递一个用于转换表的表定位符。
表格定位器引用元素的注意事项:
不得在触发器正文中指定 table-locator-reference。
- 隐含隐藏列的注意事项:
- 在触发器主体中,可引用与隐式隐藏列对应的转换变量。 转换表与包含隐含隐藏列的表相对应,将隐含隐藏列作为转换表的一部分。 同样,对于定义为隐式隐藏的列,将存在一个过渡变量。 在触发器的主体中可以引用与隐含隐藏列对应的过渡变量。
高级触发器定义中的行:
创建高级触发器时,信息会保留在 CREATE 语句的行中。 线条由新的线条控制字符决定。在高级触发器中, 新行控制字符是一种特殊字符,用于新行。 高级触发器的新行控制字符包括:- 换行符
- 新行
- 回车
- 回车,换行
- 回车,换行

解决标识符问题:
有关在触发器正文中如何将名称解析为列、SQL 变量、过渡变量或全局变量的信息,请参阅 SQL 例程的 SQL 控制语句。如果列、SQL 变量、转换变量或全局变量使用了非唯一名称,则使用列的表标识符、SQL 变量的标签名称、转换变量的相关名称和全局变量的架构来限定非唯一名称。

- AFTER和INSTEAD OF触发器中过渡变量的注意事项:
- 在AFTER或INSTEAD OF触发器中不能修改过渡变量。
- INSTEAD OF触发器的注意事项:
- 添加一个代替触发器会影响视图的只读特性。 如果只读视图与INSTEAD OF触发器存在依赖关系,则INSTEAD OF触发器定义的操作类型将决定该视图是可删除、可插入还是可更新。
如果视图定义不是只读的,则创建一个INSTEAD OF触发器会导致动态语句缓存中的相关包、计划和语句被标记为无效。
在“代替插入”触发器中可见的新过渡变量或新过渡表列的初始值设置如下:
- 如果在插入操作中为列明确指定了值,则相应的新过渡变量就是该明确指定的值。
- 如果在插入操作中未明确指定列的值,或者指定了 DEFAULT 子句,则相应的新过渡变量为:
- 如果视图列可更新(没有INSTEAD OF触发器),则为基础表列的默认值
- 否则,空值
如果视图列不可为空且没有默认值,则必须在插入操作中明确指定该值。
在“代替更新”触发器中可见的新过渡变量的初始值设置如下:
- 如果在更新操作中为某一列明确指定了值,则相应的新过渡变量就是该明确指定的值
- 如果在更新操作中为某一列明确指定了默认值(DEFAULT)条款,则相应的新转换变量为:
- 如果视图列可更新(没有INSTEAD OF触发器),则为基础表列的默认值
- 否则,空值
如果视图列不可为空且没有默认值,则必须在更新操作中明确指定该值。
- 否则,相应的新的过渡变量就是该行中列的现有值。
- MERGE语句注意事项:
MERGE 语句可以执行插入、删除和更新操作。
在执行数据更改操作时,会为 MERGE 语句激活适用的触发器。- 对于包含XML列的表格中定义的触发器的注意事项:
- 虽然可以在包含XML列的表格中定义触发器:
- 在触发器主体中,XML列不能通过转换变量进行引用。 SQL程序语句不能引用XML数据类型的转换变量。
- 在触发器主体中不能引用转换表的XML列。 SQL程序语句不能引用转换表中XML数据类型的列。
- 使用SECURED选项创建触发器:
- 通常,安全管理员会检查触发器访问的数据,确保其安全,并向需要创建安全触发器权限的人员授予CREATE_SECURE_OBJECT权限。 触发器创建后,安全管理员将撤销触发器所有者的CREATE_SECURE_OBJECT权限。
CREATE TRIGGER语句执行后,触发器即被视为安全。 Db2 将SECURED属性视为一个断言,声明用户已为触发器主体中的所有活动建立了审计程序。 如果安全触发器引用了用户定义的函数,则 Db2 会认为这些函数无需验证即可安全使用。 如果这些功能可以访问敏感数据,那么拥有SECADM权限的用户需要确保这些功能被允许访问这些数据,并且这些功能的各个版本都经过审计,而且所有后续的ALTER FUNCTION语句或对外部包的更改都经过审计流程的审查。
如果触发器的目标表使用行访问控制或列访问控制,则触发器必须安全。 如果为视图创建触发器,且视图定义中一个或多个基础表使用行访问控制或列访问控制,则还必须指定SECURED。
- 使用“未上锁”选项创建触发器:
- 如果触发器的目标表使用行访问控制或列访问控制,或者触发器用于视图,并且视图定义中的一个或多个基础表使用行访问控制或列访问控制,则CREATE TRIGGER语句将返回错误。
- 对于过渡变量和过渡表,不强制执行行和列访问控制:
- 如果对触发器的目标表实施了行访问控制或列访问控制,则行权限和列掩码不适用于转换变量和转换表的初始值。 触发表的行访问控制和列访问控制是强制性的,但对于在触发器主体中引用的过渡变量和过渡表,或者作为参数传递给在触发器主体中调用的用户定义函数,则忽略这些变量和表。 为了确保在触发器操作中访问过渡变量和过渡表中的敏感数据的SQL语句不存在安全问题,必须使用SECURED选项创建触发器。 如果触发器不安全,CREATE TRIGGER语句将返回错误。
触发器的版本:
CREATE TRIGGER 语句定义了触发器的初始版本。 只有一种版本的触发器被视为有效版本。 您可以使用ALTER TRIGGER语句的ADD VERSION子句,或者使用OR REPLACE子句和VERSION子句的CREATE TRIGGER语句(如果触发器已经存在)来定义其他版本。
当存储过程版本已经存在时,可以使用 ALTER PROCEDURE 语句的 REPLACE VERSION 子句或带有 OR REPLACE 子句和 VERSION 子句的 CREATE PROCEDURE 语句来替换版本。
对于触发器的所有版本,以下触发器属性必须相同: 触发器-激活时间、触发器-事件、 表或视图名称以及触发器-粒度。 每个触发器版本的 REFERENCING 子句内容都可能不同。
- 涉及待定义变更的限制:
- 如果触发器定义在存在待定义更改的表上,则不允许创建触发器。
- EXPLAIN的特殊计划、语句和功能表的注意事项:
- 您可以在PLAN_TABLE、DSN_STATEMNT_TABLE或DSN_FUNCTION_TABLE上创建触发器。 但是,当 Db2 向表中添加行时,这些表中定义的插入触发器不会被激活。
从属对象:
触发器依赖于触发表或视图以及触发器主体中引用的对象。
- 在触发操作中添加一个列到主题表或引用表中:
- 如果在定义触发器后向主题表中添加列,则适用以下规则:
- 如果触发器是一个没有明确列名列表的更新触发器,则对新列的更新将激活触发器。
- 如果触发操作中引用了主题表,则在重新编译触发器包之前,SQL语句无法访问新列。
- OLD_TABLE和NEW_TABLE转换表包含新列,但除非重新创建触发器,否则无法引用该列。 如果转换表被传递给用户定义的函数或存储过程,则必须使用新的表定义重新创建用户定义的函数或存储过程(即必须删除并重新创建函数或存储过程),并且必须重新绑定用户定义的函数或存储过程的包。
如果在触发操作中引用的任何表中添加列,则在新列重新绑定触发器包之前,SQL语句无法访问该列。
- 更改触发操作所引用的列的属性:
- 如果定义触发器的表(主表)中的列发生改变,则触发器将处理该改变,并使相关触发器包失效。
- 重命名已定义触发器的表格,或触发操作中引用的表格:
- 您不能重命名已定义触发器的表(主题表)。 除了主题表,您可以重命名触发操作中SQL语句引用的任何表。 重命名表后,放下触发器,然后重新创建触发器,使其指向重命名的表。
删除已定义触发器的表或视图:
如果触发器所定义的表或视图被丢弃,触发器也会被丢弃。
- 在触发操作中 ,删除或撤销对引用对象的权限会产生以下影响:
- 删除触发器正文中引用的对象,或撤销触发器正文中引用的对象的权限,可能会导致以下结果:
- 在触发操作中,删除SQL语句中引用或使用的任何表、视图、别名或索引,都会导致触发器及其包失效。
- 删除一个已引用的同义词不会对触发器或其包产生任何影响。
- 不允许删除触发操作中SQL语句引用的用户自定义函数。 发生错误。
- 不允许删除触发操作中SQL语句引用的序列。 发生错误。
- 撤销触发器所依赖的特权会导致触发器及其组件失效。 如果在触发器包被重置时不存在适当的权限,则引用该对象的SQL语句将失败。
- 触发器中的错误处理:
- 触发器可能会返回错误,就像其他SQL语句一样。 应用程序需要考虑触发器被调用时可能出现的错误。
任何异常 SQLSTATE 如果没有在触发器正文中处理(使用处理程序),都会导致异常 SQLSTATE 返回到导致触发器被激活的语句。 例如,如果一个SIGNAL语句(RESIGNAL语句或RAISE_ERROR函数) 在SQL触发器主体中引发了一个非严重错误,且该条件未在触发器主体中处理,则返回SQLCODE -438和相应的SQLSTATE。 其他非严重错误会返回SQLCODE -723和SQLSTATE 09000。 在执行触发式SQL语句时出现的严重错误将返回SQLCODE -901、-906、-911或-913以及相应的SQLSTATE。 警告不会返回。
- 触发器和全局变量:
- 触发器引用的全局变量的内容从触发SQL操作(删除、插入或更新)继承而来。
- 特别登记:
- 当触发器被激活时,触发器主体中特殊寄存器的值被确定。 CURRENT PACKAGESET特殊寄存器的值设置为触发器的模式名称,其他特殊寄存器的值从触发SQL操作(插入、更新或删除)继承。 当触发器被激活时,特殊寄存器值被保存,并在触发器返回时恢复。 当前日期、当前时间和当前时间戳特殊寄存器在触发器返回时不会恢复。
- 存储过程的执行结果集:
- 如果触发器调用一个返回结果集的存储过程,则激活触发器的应用程序无法访问这些结果集。
- 交易隔离:
- SQL触发器主体中的所有语句都在对触发器有效的隔离级别下运行。
- 限制处理器时间:
通过 Db2 资源限制功能,可以指定 SELECT 或 SQL 数据更改语句等动态、可操作 SQL 语句的最大处理器时间。 触发器的执行被算作触发SQL语句的一部分。 ASUTIME 触发器选项可用于指定这种限制。
- 绑定触发器的错误:
- 绑定CREATE TRIGGER语句时,触发操作中的SQL语句可能无法完全解析。 这些语句中的语法错误可能直到执行CREATE TRIGGER语句时才会被发现。
- 为触发器生成的包的特征:
- 与触发器关联的包的命名如下:
- 位置设置为当前服务器特殊寄存器的值。
- 包的collection-id (模式)与触发器的模式限定符相同。
- package-id 与触发器的名称相同。
软件包使用与隐式或显式指定的触发器选项相对应的绑定选项生成。 更多信息请参见表2。 除相应的绑定选项外,软件包还使用以下绑定选项生成:

- FLAG(I)
- sqlerror(nopackage)
- 启用(*)
- 确认(绑定)

如果触发器所依赖的对象或权限被删除或撤销,则触发器包将失效。 下次触发器被激活时, Db2 将尝试重新绑定无效的触发器包。 如果自动重新绑定失败,触发器包将保持无效状态。
您不能从触发包创建另一个软件包,例如使用 BIND COPY 命令。 删除触发器包的唯一方法是删除触发器或主题表或视图。 丢弃触发器会丢弃触发器包;丢弃主题表或视图会丢弃触发器和触发器包。
每次触发器被激活时,触发器组件都会执行一次或多次。
- SQL处理器程序的注意事项:
- SQL处理器程序(例如SPUFI、 Db2 command line processor 和 DSNTEP2 )可能无法正确解析触发操作中以分号结尾的SQL语句。 这些处理器程序接受多个SQL语句作为输入,每个语句以一个终止符分隔。 使用分号作为SQL语句终止符的处理器程序可能会截断带有嵌入分号的CREATE TRIGGER语句,仅将其中一部分传递给 Db2。 因此,您可能需要为这些处理器程序更改 SQL 终止符。 有关更改SPUFI和 DSNTEP2 的终止符的信息,请参阅 《在SPUFI输入数据集中设置SQL终止符 》以及 DSNTEP2 和 DSNTEP4 示例程序。
- 触发对象的应用兼容性级别注意事项
- 应用程序兼容性级别控制着新功能和增强功能的采用和使用。 当一个对象被创建或修改时,会使用两个单独的应用程序兼容级别:一个用于处理对象的定义,另一个用于处理对象正文中的SQL语句:
对象定义 当前应用程序兼容性特殊寄存器值用于处理对象定义,但对象主体中的语句除外
此应用程序兼容性级别存储在 SYSENVIRONMENT.APPLCOMPAT 列中。 您可以在对象的目录定义中使用环境ID值来定位具有匹配ENVID值的SYSENVIRONMENT行。
当对象被重新生成时,应用程序兼容性级别可以更改。
物体主体中的陈述 CREATE或ALTER语句的APPLCOMPAT选项隐式或显式指定的应用程序兼容性级别用于处理对象主体中的语句。
此应用程序兼容性级别存储在与对象定义关联的软件包的 SYSPACKAGE.APPLCOMPAT 列中。
- 其他语法和同义词:
- 为了与 Db2 的早期版本或 Db2 系列中的其他产品兼容, Db2 支持以下关键词:
- OLD TABLE作为OLD_TABLE的同义词
- NEW TABLE作为NEW_TABLE的同义词
混淆视听的发言:
FL 500A CREATE TRIGGER 语句可以混淆形式执行。 在一份模糊不清的声明中,只有触发器名称和WRAPPED关键字可以读取。 该语句的其余部分将以不可读方式进行编码,但支持模糊语句的数据库服务器可以解码该部分。 WRAP标量函数生成混淆语句。 根据混淆语句创建触发器时指定的任何调试选项都会被忽略。
CREATE TRIGGER(高级)示例
- 示例 1
- 创建两个触发器,用于跟踪公司管理的员工数量。 主表是员工表,触发器根据公司统计表中的员工总数来增减列。 表格包含以下列:
- 员工表:ID、姓名、地址和职位
- COMPANY_STATS表:NBEMP、NBPRODUCT和REVENUE
这个示例展示了如何在行触发器中使用过渡变量来维护另一个表中的汇总数据。
创建第一个触发器 NEW_HIRE,使其在每次有新人被雇佣时都会增加雇员人数;也就是说,每次在 EMPLOYEE 表中插入新记录时,都会将 COMPANY_STATS 表中 NBEMP 列的值增加 1。
CREATE TRIGGER NEW_HIRE AFTER INSERT ON EMPLOYEE FOR EACH ROW BEGIN ATOMIC UPDATE COMPANY_STATS SET NBEMP = NBEMP + 1; END
创建第二个触发器 FORM_EMP,以便在每次有员工离职时递减员工人数;也就是说,每次从表 EMPLOYEE 中删除一条记录时,将表 COMPANY_STATS 中 NBEMP 列的值减少 1。
CREATE TRIGGER FORM_EMP AFTER DELETE ON EMPLOYEE FOR EACH ROW BEGIN ATOMIC UPDATE COMPANY_STATS SET NBEMP = NBEMP - 1; END
- 示例 2
创建一个触发器 REORDER,调用用户定义的函数 ISSUE_SHIP_REQUEST,以便在更新零件记录且受影响零件的在手数量少于最大库存数量的 10% 时发出出货请求。 用户定义函数 ISSUE_SHIP_REQUEST 订购的零件数量等于零件的最大库存量减去库存量;确保将请求发送给适当的供应商,并返回订购的数量。
零件记录在零件表中。 虽然表格列数更多,但只有在ON_HAND和MAX_STOCKED列更新时才会触发。
CREATE TRIGGER REORDER AFTER UPDATE OF ON_HAND, MAX_STOCKED ON PARTS REFERENCING NEW AS NROW FOR EACH ROW WHEN (NROW.ON_HAND < 0.10 * NROW.MAX_STOCKED) BEGIN ATOMIC DECLARE QTY_ORDERED INTEGER; VALUES(ISSUE_SHIP_REQUEST(NROW.MAX_STOCKED - NROW.ON_HAND, NROW.PARTNO)) INTO QTY_ORDERED; END- 示例 3
- 重复示例2中的场景,但使用SELECT INTO语句代替VALUES INTO语句来调用用户定义的函数。 这个示例还展示了如何将触发器定义为语句触发器,而不是行触发器。 对于转换表中WHERE子句计算结果为true的每一行,都会发出零件的运输请求。

CREATE TRIGGER REORDER AFTER UPDATE OF ON_HAND, MAX_STOCKED ON PARTS REFERENCING NEW_TABLE AS NTABLE FOR EACH STATEMENT BEGIN ATOMIC DECLARE QTY_ORDERED INTEGER; SELECT ISSUE_SHIP_REQUEST(MAX_STOCKED - ON_HAND, PARTNO) FROM NTABLE WHERE (ON_HAND < 0.10 * MAX_STOCKED) INTO QTY_ORDERED; END
- 示例 4
- 假设表EMPLOYEE包含列SALARY。 创建一个触发器SAL_ADJ,防止员工工资更新超过20%,并发出错误信号。 错误信息为SQLSTATE '75001',并附带描述。 本例说明,SIGNAL 语句可用于限制违反业务规则的更改。

CREATE TRIGGER SAL_ADJ AFTER UPDATE OF SALARY ON EMPLOYEE REFERENCING OLD AS OLD_EMP NEW AS NEW_EMP FOR EACH ROW WHEN (NEW_EMP.SALARY > (OLD_EMP.SALARY * 1.20)) BEGIN ATOMIC SIGNAL SQLSTATE '75001' ('Invalid Salary Increase - Exceeds 20 END
- 示例 5
- 假设以下语句创建了一个表 WEATHER(存储华氏温度值)和一个视图 CELSIUS_WEATHER,供那些习惯使用摄氏温度而非华氏温度的用户使用:
在 CELSIUS_WEATHER 视图中使用以下 INSTEAD OF 触发器将摄氏度值转换为华氏度值,然后将华氏度值插入 WEATHER 表:CREATE TABLE WEATHER (CITY VARCHAR(25), TEMPF DECIMAL(5,2)); CREATE VIEW CELSIUS_WEATHER (CITY, TEMPC) AS SELECT CITY, (TEMPF-32)/1.8 FROM WEATHER;
CREATE TRIGGER CW_INSERT INSTEAD OF INSERT ON CELSIUS_WEATHER REFERENCING NEW AS NEWCW FOR EACH ROW BEGIN ATOMIC INSERT INTO WEATHER VALUES (NEWCW.CITY, 1.8*NEWCW.TEMPC+32) END;
- 示例 6
- 创建一个更新前的触发器STOCK_STATUS,使用逻辑记录并跟踪股票价格的变化。
假设数据库包含两个表,CURRENTQUOTE和QUOTEHISTORY。 CURRENTQUOTE包含SYMBOL、QUOTE和STATUS列。 QUOTEHISTORY包含SYMBOL、QUOTE和QUOTE_TIMESTAMP列。
当“当前报价”的“报价”列更新时,必须将带有时间戳的新报价复制到“报价历史”表中。 此外,必须更新当前报价的“状态”栏,以反映库存是否:

1 价值上升 2 创下年度新高 3 贬值 4 创下年度新低 5 价值稳定 
完成这些任务的CREATE TRIGGER语句如下:
触发器 STOCK_STATUS 设置状态:

CREATE TRIGGER STOCK_STATUS NO CASCADE BEFORE UPDATE OF QUOTE ON CURRENTQUOTE REFERENCING NEW AS NEWQUOTE OLD AS OLDQUOTE FOR EACH ROW BEGIN ATOMIC SET NEWQUOTE.STATUS = CASE WHEN NEWQUOTE.QUOTE > (SELECT MAX(QUOTE) FROM QUOTEHISTORY WHERE SYMBOL = NEWQUOTE.SYMBOL AND YEAR(QUOTE_TIMESTAMP) = YEAR(CURRENT DATE) ) THEN 'High' WHEN NEWQUOTE.QUOTE < (SELECT MIN(QUOTE) FROM QUOTEHISTORY WHERE SYMBOL = NEWQUOTE.SYMBOL AND YEAR(QUOTE_TIMESTAMP) = YEAR(CURRENT DATE) ) THEN 'Low' WHEN NEWQUOTE.QUOTE > OLDQUOTE.QUOTE THEN 'Rising' WHEN NEWQUOTE.QUOTE < OLDQUOTE.QUOTE THEN 'Dropping' WHEN NEWQUOTE.QUOTE = OLDQUOTE.QUOTE THEN 'Steady' END; END
触发器 RECORD_HISTORY 记录 QUOTEHISTORY 表中的更改:
CREATE TRIGGER RECORD_HISTORY AFTER UPDATE OF QUOTE ON CURRENTQUOTE REFERENCING NEW AS NEWQUOTE FOR EACH ROW BEGIN ATOMIC INSERT INTO QUOTEHISTORY VALUES (NEWQUOTE.SYMBOL, NEWQUOTE.QUOTE, CURRENT TIMESTAMP); END - 示例 7
- 创建一个插入前触发器 NEW_HIRED,该触发器使用逻辑来说明与在触发器主体中声明的 SQL 变量相比,转换变量的不同作用域。 假设雇员表定义如下:
CREATE TABLE EMPLOYEE (EMPNO CHAR(6), FIRSTNAME VARCHAR(32), WORKDEPT CHAR(5), NUM INTEGER)#在触发器NEW_HIRED中,新值的转换变量的相关名称为XYZ,XYZ也是复合语句的标签,其中定义了SQL变量。 表中有一列名为NUM,SQL变量也名为NUM。 赋值语句中 XYZ.NUM 的引用是指SQL变量,因为这是赋值语句中局部作用域最大的定义。
CREATE TRIGGER NEW_HIRED BEFORE INSERT ON EMPLOYEE REFERENCING NEW AS XYZ FOR EACH ROW XYZ: BEGIN DECLARE NUM INTEGER; SET XYZ.NUM = XYZ.NUM + 1; END XYZ#假设发出以下INSERT语句:
INSERT INTO EMPLOYEE VALUES ('000001', 'RICK', 'DPT01', 10)#表中值与INSERT语句的VALUES子句中最初指定的值相同。 这意味着NUM转换变量不受赋值语句的影响。 任务语句中 XYZ.NUM 的引用指向SQL变量NUM,而不是过渡变量NUM。
在INSERT语句运行后,发出以下SELECT语句查看结果:
SELECT * FROM EMPLOYEE#结果为:

EMPNO FIRSTNAME WORKDEPT NUM 000001 里克 DPT01 10 
- 示例 8
- 使用逻辑创建一个插入前触发器,以强制执行以下规则:如果在插入到 CLASS_SCHED 时未提供结束时间,则课程将在开始后一小时结束。 定义触发器,以执行晚上 9 点后不得下课的额外限制。

CREATE TRIGGER VALIDATE_SCHED BEFORE INSERT ON CLASS_SCHED REFERENCING NEW AS N FOR EACH ROW WHEN (N.ENDING IS NULL OR N.ENDING > '21:00') VS: BEGIN -- SUPPLY DEFAULT VALUE FOR ENDING TIME IF NULL IF (N.ENDING IS NULL) THEN SET N.ENDING = N.STARTING + 1 HOUR; END IF; -- ENSURE THAT CLASS DOES NOT END BEYOND 9PM IF (N.ENDING > '21:00') THEN SIGNAL SQLSTATE '80000' SET MESSAGE_TEXT = 'CLASS ENDING TIME IS BEYOND 9 PM'; END IF; END VS
例 9: 更改触发器 VALIDATE_SCHED,以更改限制,使课程结束时间不能超过下午 7 点。 OR REPLACE子句被添加到原始的CREATE TRIGGER语句中,规则被修改为检查结束时间( N.ENDING > '19:00')。 CREATE TRIGGER 语句会用更新的定义替换触发器的现有定义。

CREATE OR REPLACE TRIGGER VALIDATE_SCHED BEFORE INSERT ON CLASSES REFERENCING NEW AS N FOR EACH ROW -- TRIGGER WHEN CLAUSE WHEN (N.ENDING IS NULL OR N.ENDING > '19:00') VS: BEGIN -- SUPPLY DEFAULT VALUE FOR ENDING TIME IF NULL IF (N.ENDING IS NULL) THEN SET N.ENDING = N.STARTING + 1 HOUR; END IF; -- ENSURE THAT CLASS DOES NOT END BEYOND 7 PM IF (N.ENDING > '19:00') THEN SIGNAL SQLSTATE '80000' SET MESSAGE_TEXT = 'CLASS ENDING TIME IS BEYOND 7 PM'; END IF; END VS

