语法
CREATE TRIGGER trigger_name -- 触发器名称必须符合标识符规则,并且在数据库中必须唯一。可以选择是否指定触发器所有者名称。
ON { table | view } -- 可以选择是否指定表或视图的所有者名称。
[ WITH ENCRYPTION ] -- 加密触发器
{
--for=after, 不能在视图上定义 AFTER 触发器。
--INSTEAD OF指定执行触发器而不是执行触发 SQL 语句,从而替代引起触发器sql语句的操作。
{ { FOR | AFTER | INSTEAD OF } { [ INSERT ][ , ] [DELETE] [ , ] [ UPDATE ] }
[ WITH APPEND ] -- 指定应该添加现有类型的其它触发器
[ NOT FOR REPLICATION ] --当复制进程更改触发器所涉及的表时,不应执行该触发器。
AS -- 触发器要执行的操作
[ { IF UPDATE ( column )
[ { AND | OR } UPDATE ( column ) ]
[ n ]
-- bitwise_operator 是用于比较运算的位运算符
| IF ( COLUMNS_UPDATED ( ) { bitwise_operator } updated_bitmask )
{ comparison_operator } column_bitmask [ n ]
} ]
sql_statement [ n ]
}
}
注:{}表示必须选择内部一值,[ ]表示可选字段
INSTEAD OF:在表或视图上,每个 INSERT、UPDATE 或 DELETE 语句最多可以定义一个 INSTEAD OF 触发器。
然而,可以在每个具有 INSTEAD OF 触发器的视图上定义视图。INSTEAD OF 触发器不能在 WITH CHECK OPTION 的可更新视图上定义。如果向指定了 WITH CHECK OPTION 选项的可更新视图添加 INSTEAD OF 触发器,SQL Server 将产生一个错误。用户必须用 ALTER VIEW 删除该选项后才能定义 INSTEAD OF 触发器。
IF (COLUMNS_UPDATED()):测试是否插入或更新了提及的列,仅用于 INSERT 或 UPDATE 触发器中。
COLUMNS_UPDATED 返回varbinary 位模式,表示插入或更新了表中的哪些列。COLUMNS_UPDATED 函数以从左到右的顺序返回位,最左边的为最不重要的位。最左边的位表示表中的第一列;向右的下一位表示第二列,依此类推。
如果在表上创建的触发器包含 8 列以上,则 COLUMNS_UPDATED 返回多个字节,最左边的为最不重要的字节。在 INSERT 操作中 COLUMNS_UPDATED 将对所有列返回 TRUE 值,因为这些列插入了显式值或隐性 (NULL) 值。可以在触发器主体中的任意位置使用 COLUMNS_UPDATED。
触发器特性
- 触发器可以包含任意数量和种类的 Transact-SQL语句
- 触发器旨在根据数据修改语句检查或更改数据
- 它不应将数据返回给用户
理解触发器里的两个临时表:Deleted , Inserted
注意Deleted 与Inserted分别表示触发事件的表“旧的一条记录”和“新的一条记录”。
在触发器中可加入事务处理
CREATE TRIGGER triggerName
ON tableName
FOR INSERT ,UPDATE
AS
--提交事务处理
BEGIN
TRANSACTION
--检查合法性
--检查数据的合法性:销售的卷烟是否有库存,或者库存是否大于零
IF NOT EXISTS ()
BEGIN
--返回错误提示
RAISERROR('错误信息' ,16, 1)
--回滚事务
ROLLBACK
RETURN
END
--检查完成,若正常则往下处理
--正常,trigger code
COMMIT TRANSACTION
end
实例
建立表jor(mnum ,mname ,inum ) student(sid ,sex ,major ,schoolYear )
其中,student 的 sid 列包含 jor.mnum 列的信息
目的:在插入student 的 sid 列时,根据 sid 信息自动查询jor表的munm,将 mname自动插入student.major
--jor表
CREATE TABLE jor
(
mnum char (3) PRIMARY KEY ,
mname varchar (48) NOT NULL,
inum varchar (2) NOT NULL
)
--插入数据
INSERT INTO jor VALUES ('004' ,'经济专业','11' )
INSERT INTO jor VALUES ('005' ,'机电专业','12' )
INSERT INTO jor VALUES ('006' ,'英语专业','12' )
select * from jor;
--student表
drop table student
CREATE TABLE student
(
sid varchar (10) PRIMARY KEY ,
sex as convert( bit,substring (sid, 2,1 ))persisted not NULL, --DEFAULT '0' 0:man,1:woman;
major varchar (48),
paperStatus char (1) NOT NULL CHECK (paperstatus in('1', '2','3' ,'4') ) DEFAULT '1' ,--1:未选题,2:审核中,3重新选题,4已选题
schoolYear as convert( char(2 ),substring( sid,3 ,2)) persisted not NULL
)
select * from student
--使用test数据库
USE test
GO
--已存在trigger则先删除再创建
IF EXISTS(
SELECT *
FROM sys .triggers
WHERE name = N'studenttrigger'
AND parent_class_desc = N'test'
)
DROP TRIGGER studenttrigger ON DATABASE
GO
--创建
CREATE TRIGGER studenttrigger
ON student
FOR INSERT ,UPDATE
AS if update (sid) --更新sid列,sid列为主键,不可更新,update无意义
BEGIN
declare @sid char( 10) --声明变量
select @sid =sid from inserted --inserted表示新表变量
update student set major=(select mname from test .dbo. jor where mnum in (Select SUBSTRING( @sid,5 ,3))) where sid=@sid
end
--测试
INSERT INTO student( sid) VALUES ('123456789' )
INSERT INTO student( sid) VALUES ('2512006770' )
update student set sid= '2512005770' where sid= '2512006770'--sid列为主键,不可更新
delete student where sid= '2512006770'
select * from student
参考文献:
SQL触发器语法参考