SQL Server 触发器

1、概念
触发器是一种特殊的存储过程,它不能被显式地调用,而是在往表中插入记录﹑更新记录或者删除记录时被自动地激活,自动执行的存储过程。 所以触发器可以用来实现对表实施复杂的完整性约束。

2、deleted 表和 inserted 表
触发器语句中使用了两种特殊的表:deleted 表和 inserted 表。
Deleted 表用于存储 DELETE 和 UPDATE 语句所影响的行的复本
Inserted 表用于存储 INSERT 和 UPDATE 语句所影响的行的副本

1.插入操作(Insert)
Inserted表有数据,Deleted表无数据

2.删除操作(Delete)
Inserted表无数据,Deleted表有数据

3.更新操作(Update)
Inserted表有数据(新数据),Deleted表有数据(旧数据)

4.查询所有触发器

select * from Sysobjects where xtype = 'TR'

select name from sysobjects where instrig=(select id from sysobjects where xtype='TR')

select a.name 数据表名
,sysobjects.name as 触发器名
,sysobjects.crdate as 创建时间 
from sysobjects
left join (select *from sysobjects where xtype='U')as a on sysobjects.parent_obj=a.id
where sysobjects.xtype= 'TR'

select object_name(a.parent_obj) as [表名]
,a.name AS [触发器名称]
,(case when b.is_disabled = 0 then '启用' else '禁用' end) as [状态]
,b.create_date as [创建日期]
,b.modify_date as [修改日期]
,c.text as [触发器语句]
from sysobjects a
INNER JOIN sys.triggers b ON b.object_id = a.id
INNER JOIN syscomments c ON c.id = a.id
--where a.xtype = 'tr' and c.text like '%bom_weight_wkx%'
order by [表名]

--select distinct  b.name,b.type from dbo.syscomments a,  dbo.sysobjects b where a.id = b.id AND b.xtype = 'p'  AND a.text like '%ORG_PATIENT%'

3、触发器类型
SQL Server 有3类触发器【触发器是在对应表的下面
Insert:向数据表插入数据时,调用insert触发器。
Update:更新数据时调用update触发器。
Delete:删除数据时执行Delete触发器。
Sql server中这三类触发器总是在执行操作语句后才被自动调用。

4、工作原理
After(同for):先执行增、删、改、操作,再激活触发器操作。
Instead of:在执行增、删、改、操作之前,先激活触发器。

5、语法
查看数据库已有触发器

select * from sysobjects where xtype='TR'

查看单个触发器

exec sp_helptext 'bed_insert'

基础语法

create trigger 触发器名
on 表名
[for,after,Instead of]
[delete,insert,update]
as

--语法
Create trigger trigger_name----创建名称
On {table|view}----定义在表或者视图上
[with encryption]----加密元数据
{
{ {for|after|instead of}{[insert][,][update][,][delete]}触发器执行的条件
 [with append]
 [ont for replication]
As----触发器要执行的操作
[ {if update(column)----判断执行的是什么操作
 [{and|or}update(column)][,…n]
 |if(columns_updated(){bitwise_operator}updated_bitmask)----判断是否插入跟新了数据
 {comparison_operator}column[,…n]
}]
Sql_statement[,…n]操作语句
 }
}

--语法
create or REPLACE TRIGGER salary_raiu
AFTER INSERT OR UPDATE OF amount ON salary
FOR EACH ROW
BEGIN
    IF inserting THEN
        dbms_output.put_line(‘插入’)
    ELSIF updating THEN
dbms_output.put_line(‘更新amount列’)
         END IF
END

insert触发器【实战】

--示例1【sys_user表插入触发器】
CREATE trigger [dbo].[trigger_user_insert]
on [dbo].[sys_user]
for insert
as
declare @id int,@user_name varchar(255),@real_name nvarchar(255)
select @id=id,@user_name=user_name,@real_name=real_name from sys_user
--判断【sys_user】表中【id=?】的数据是否存在
if @id not in(select id from sys_user)
begin
 rollback transaction
 print '用户表中不存在的id,取消插入数据'
 return
end
--判断【sys_department】表中【id=2】的数据是否存在
else if 2 not in(select id from sys_department)
begin
  print '部门表中不存在的id,取消插入数据'
  rollback transaction
end
else
begin
  print convert(nvarchar(255),@id) + ',' + @user_name + ',' + @real_name
  insert into [dbo].[sys_user_department] (user_id,department_id,created_time,modify_time,status) values (@id,1,getdate(),getdate(),'A')
end
GO

ALTER TABLE [dbo].[sys_user] ENABLE TRIGGER [trigger_user_insert]
GO


--示例2【sys_user_department插入触发器】
CREATE trigger [dbo].[trigger_user_department_insert]
on [dbo].[sys_user_department]
for insert
as
declare @user_id int,@department_id int
select @user_id=user_id,@department_id=department_id from sys_user_department
--判断【sys_user】表中【id=?】的数据是否存在
if @user_id not in(select id from sys_user)
begin
 print '用户表中不存在的id,取消插入数据'
 rollback transaction
end
--判断【sys_department】表中【id=?】的数据是否存在
else if @department_id not in(select id from sys_department)
begin
  print '部门表中不存在的id,取消插入数据'
  rollback transaction
end
else
begin
  print '插入成功!'
end
GO


insert触发器

create trigger bed_insert 
on base_bed 
for insert
as
select * from base_bed


--示例1
create trigger trigger_insert
on score
for insert
as
declare @xuehao int,@kehao int
select @xuehao=学号,@kehao=课号
from inserted
if @xuehao not in(select 学号 from student)
begin
 rollback transaction
 print'学生表中不存在的学号,取消插入数据'
end
if @kehao not in(select 课号 from course)
begin
 rollback transaction
 print'成绩表中不存在的课号,取消插入数据'
end


--示例2
create trigger tri_Insert 
on Borrow 
after insert
as
    --先要判断该书在不在馆
    if not exists(select bkState from Book, inserted where Book.bkID = inserted.bkID)
    begin
        raiserror('该书不在馆,无法插入!',10,1)
        return
    end

    update Reader set rdBorrowQty = rdBorrowQty + 1
    from Reader, inserted
    where Reader.rdID = inserted.rdID

    update Book set bkState = 0
    from Book, inserted
    where Book.bkID = inserted.bkID

--调用:
insert into Borrow values ('rd2017004','bk2017004',GETDATE(),30,null)


--示例3【限制插入】
create trigger dept_emp_insert
on emp
after insert
as
if(select inserted.deptid from dept,inserted where dept.id = inserted.deptid) = 2
begin
   print 'the emp is full'
   rollback transaction
end

update触发器

create trigger user_update 
on base_bed 
for update
as 
select * from base_bed

delete触发器

create trigger user_delete 
on base_bed 
for delete
as 
select * from base_bed

insert,update,delete触发器

create trigger user_cud
on base_bed 
for insert,update,delete
as
select * from base_bed

*
*
*

  • 2
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值