接触触发器
分类:SQL Server|评论:0 条|阅读:2479 次|posted @ 2008年11月9日 22:53:35触发器是数据库服务器中发生事件时自动执行的特种存储过程。如果用户要通过数据操作语言 (DML) 事件编辑数据,则执行 DML 触发器。DML 事件是针对表或视图的 INSERT、UPDATE 或 DELETE 语句。
现在有一个这样的需求,想在插入新数据到 news 表时,先对 title 字段进行检查,要是有相同数据的就停止插入。
先创建一个触发器:checknews
CREATE TRIGGER checknews -- checknews 为触发器名称
ON news -- ON 后面是触发器所属表
AFTER INSERT -- 触发器类型
AS
begin
if exists(select 1 from inserted join news on inserted.title=news.title)
ROLLBACK TRANSACTION
end
咋一看,没什么问题,其实达不到我们想要的效果;指定触发器类型有三个关键词,分别是:FOR, AFTER, INSTEAD OF
AFTER:它是先执行操作,再运行触发器的,像上面的触发器,是永远都无法往表添加记录的。
FOR:如果仅指定 FOR 关键字,则 AFTER 为默认值,经测试我觉得 AFTER 和 FOR 为同样的效果。
INSTEAD OF:它不执行其所定义的操作(INSERT,UPDATE,DELETE),也就是用户操作,而执行触发器本身!也就是说,尽管触发器被触发,但相应的操作并不执行,而运行的仅是触发器 SQL 语句本身。对于统一操作只能定义一个 INSTEAD OF 触发器!
明白以上的,改一下触发器:
CREATE TRIGGER checknews
ON news
AFTER INSERT
AS
begin
declare @count int
select @count = count(*) from inserted join news on inserted.title=news.title
if @count > 1
ROLLBACK TRANSACTION -- 回滚
end
至此,需求就实现了,如果说一定要用 exists,怎么实现呢?那就用 INSTEAD OF 了。
CREATE TRIGGER checknews
ON news
INSTEAD OF INSERT
AS
begin
if not exists(select 1 from inserted join news on inserted.title=news.title)
INSERT INTO news SELECT [title], [image] FROM inserted
end
刚接触触发器(我就是)的朋友可能会问 inserted 是什么?它是一个临时表,还有 deleted,均是用在触发器的,详细介绍请看: