SQL触发器全过程(含实例讲解)

合集下载

SQL触发器的使用及语法

SQL触发器的使用及语法

===以下转/blog/424789定义:何为触发器?在SQL Server里面也就是对某一个表的一定的操作,触发某种条件,从而执行的一段程序。

触发器是一个特殊的存储过程。

常见的触发器有三种:分别应用于Insert , Update , Delete 事件。

我为什么要使用触发器?比如,这么两个表:Create Table Student( --学生表StudentID int primary key, --学号....)Create Table BorrowRecord( --学生借书记录表BorrowRecord int identity(1,1), --流水号StudentID int , --学号BorrowDate datetime, --借出时间ReturnDAte Datetime, --归还时间...)用到的功能有:1.如果我更改了学生的学号,我希望他的借书记录仍然与这个学生相关(也就是同时更改借书记录表的学号);2.如果该学生已经毕业,我希望删除他的学号的同时,也删除它的借书记录。

等等。

这时候可以用到触发器。

对于1,创建一个Update触发器:Create Trigger truStudentOn Student --在Student表中创建触发器for Update --为什么事件触发As --事件触发后所要做的事情if Update(StudentID)beginUpdate BorrowRecordSet StudentID=i.StudentIDFrom BorrowRecord br , Deleted d ,Inserted i --Deleted和Inserted临时表Where br.StudentID=d.StudentIDend理解触发器里面的两个临时的表:Deleted , Inserted 。

注意Deleted 与Inserted分别表示触发事件的表“旧的一条记录”和“新的一条记录”。

SQL菜鸟入门级教程之触发器

SQL菜鸟入门级教程之触发器

SQL菜鸟入门级教程之触发器本人水平有限,写此博客只为给那些像我一样的菜鸟一点小小的帮助,还请各位大牛不要见笑。

数据库的重要性就不用我多说了吧,我们做的大多数项目都要跟数据库打交道。

因此,熟练掌握数据库的各种操作,就成了一个程序员必备的技能。

今天我们就来简单说一下触发器。

触发器简介:触发器(trigger)是种特殊的存储过程,它的执行不是由程序调用,也不需要手动操作,它是由事件来触发,事件大家应该非常熟悉吧,比如按钮的Click事件、网页的Load事件等。

按钮的Click事件是通过鼠标单击按钮触发的,而触发器的事件,是由对表进行增删改操作所触发的。

当对一个数据库或表进行增删改(Insert,Delete,Update)的时就会激活触发器。

从SQL2005开始,根据SQL语句的不同将触发器分成了两类,一类是DML触发器,一类是DLL触发器。

其中DML触发器又分为两类:After触发器和Instead Of触发器。

触发器的分类:DML触发器:DML(Data Manipulation Language)触发器是当数据库服务器中发生数据操作语言事件时执行的存储过程。

DML触发器又分为两类:After触发器和Instead Of触发器DDL触发器:DDL触发器是在响应数据定义语言(Data Definition Language)事件时执行的存储过程。

DDL触发器一般用于执行数据库中管理任务。

如审核和规范数据库操作、防止数据库表结构被修改等。

DML触发器:今天我们我们主要介绍DML触发器,DML触发器分为After触发器和Instead Of触发器。

After触发器:这类触发器是在记录已经改变完之后(after),才会被激活执行,它主要是用于记录变更后的处理或检查,一旦发现错误,也可以用Rollback Transaction语句来回滚本次的操作。

Instead Of触发器:这类触发器一般是用来取代原本的操作,在记录变更之前发生的,它并不去执行原来SQL语句里的操作(Insert、Update、Delete),而去执行触发器本身所定义的操作。

SQL触发器实例

SQL触发器实例

--建立触发器,显示修改人数create trigger d1 on jun for insert,update asselect '你正在修改数据'declare @a varchar(20)select @a=str(@@rowcount)+'个学生被修改'select @aselect * from junreturninsert into jun(爱好) values('跑步')update jun set 爱好='打球' where 学号<='103'--建立触发器,当男生人数在6个以内可以加入,否则不能加入create trigger i1 on zg for insert asif((select count(性别) from zg where 性别='男')>6)select '不能插入,男生人数已满。

'elseselect'插入成功'select * from zginsert into zg(学号,姓名,性别) values(20100636,'江渝','男')--建立触发器,如果语文成绩在200以内可以修改,否则不能修改create trigger u1 on zg for update asif((select max(语文) from zg )>200)beginselect '你不能修改'rollbackendelseselect '修改成功'select * from zgupdate zg set 语文=语文+10 where 姓名='唐荣强'update zg set 语文=语文-20 where 姓名='张军'update zg set 语文=语文+30 where 姓名='张军'--建立触发器,显示删除和修改的内容create trigger d2 on zg for insert,update,delete asselect * from deletedselect * from insertedselect * from zgdelete from zg where 班级=Nulldelete from zg where 姓名='张军'--建立触发器,如果zg表中没有此人的姓名,则不能在kc表中进行修改create trigger i2 on kc for insert,update asif(not exists(select 姓名from zg where 姓名=(select 姓名from inserted))) beginselect '不能修改数据'rollbackselect * from kcendelsebeginselect '修改成功'select * from kcendupdate kc set 选修人数=选修人数+100 where 姓名='张军'--建立触发器,更行zg时也更新kccreate trigger u2 on zg for update asselect * from deletedselect * from insertedupdate kc set 姓名=(select min(姓名) from inserted )where 姓名=(select min(姓名) from deleted)select * from zgselect * from kcupdate zg set 姓名='张晓军' where 姓名='张军'--建立触发器,如果加入的数>2000就不能插入并将默认值为500create trigger i3 on zg for insert asif((select 语文from inserted)>2000)beginselect '语文>2000不合适'update zg set 语文=500select * from zgrollbackendelseselect '修改成功'insert into zg(班级,姓名,学号,语文) values('小数','王五',20100637,2500)--建立触发器,不能删除总成绩最高的人create trigger d3 on zg for delete asif( select 总成绩from deleted) >= ( select max(总成绩)from zg)beginselect '删除的数为:'select * from deletedselect '不能删除成绩最高的一位'rollbackendelseselect '删除成功'select * from zgdelete from zg where 姓名='唐荣强'--建立触发器,英语增长不超过250%create trigger u3 on zg for update asif(select max(英语) from inserted )/(select min(英语) from deleted)>2.5beginselect * from deletedselect * from insertedselect '增长速度>250%不能修改'rollbackendelseselect '修改成功'select * from zgupdate zg set 英语=英语*3 where 姓名='杨杰'--通过触发器调用其他函数create proc p1 asselect * from zgcreate trigger u4 on zg for insert,delete,update asexec p1insert into zg(姓名,学号,班级)values('小王',20100638,'小语')--多个触发器运行顺序create trigger i5 on zg for insert,update asselect '你在插入数据'create trigger u5 on zg for update,insert asselect '你在修改数据'update zg set 姓名='张军' where 姓名='张晓军'--触发器create trigger j1 on kc for update,delete,insertasselect( '你正在修改数据');select * from deleteddelete from kc where 课程名称='计算机导论'insert into kc (学号,课程名称,课程代码,学分) values('1010','计算机导论','D032T',2) update kc set 学号=1007 where 学号=1006create trigger j2 on kc for deleteasdeclare @count varchar(20)select @count=str(@@rowcount)+'个学生被删除'select @countreturndelete from kc where 学分=1.5create trigger j3 on jun for insert,updateasif(select sum(年龄) from jun )>400beginselect '你们年龄大入要求:不予录取'rollbackendelsebeginselect '恭喜你,你被录取了'endinsert into jun (学号,爱好,年龄) values('111','编程',20)update zg set 总成绩=语文+数学+英语select * from zgcreate trigger y2 on zg for insert,updateasif( select sum(总成绩) from zg )>2000beginselect ' 你通过了考试,欢迎你晋级'rollbackendelseselect '很抱歉,你没有通过考试'select * from zgupdate zg set 语文=语文-50 select 语文from zg。

SQLSERVER触发器(附有实例)

SQLSERVER触发器(附有实例)

SQLSERVER触发器(附有实例)触发器:即当发⽣某⼀事件时,如果满⾜给定条件,则执⾏相应的动作。

它的基本架构:触发器创建语法:(1)CREATETRIGGER trigger_nameON table|viewFOR|AFTER|INSTEADOF [DELETE][,INSERT][,UPDATE]ASSql_statement[…n](2)CREATETRIGGER trigger_nameON table|viewFOR|AFTER|INSTEADOF [DELETE][,INSERT][,UPDATE]ASIFUPDATE(column)[{AND|OR}UPDATE(COLUMN)][…]IF(COLUMNS_UPDATED())Sql_statement[…n]注:(不同数据库⽀持不同的类型触发器,有些还⽀持before类型触发器,像SQL server 就不⽀持before触发器)SQL Server⽀持两种类型的触发器AFTER触发器和INSTEAD OF 触发器,其中、AFTER触发器要求只有执⾏某⼀操作ISERT, UPDATE ,DELETE之后触发器才被触发。

1)INSTEAD OF 触发器表⽰并不执⾏其所定义的操作INSERT,UPDATE ,DELETE,⽽仅是执⾏触发器本⾝,既可在表上定义INSTEAD OF 触发器,也可以在视图上定义INSTEAD OF 触发器。

2)after 触发器(也叫“FOR”触发器)则会在触发 insert、update 或是delect 动作之后执⾏。

触发事件分为三类:UPDATE、DELETE和INSERT。

另外,定义触发器时,系统都都会⾃动⽣成两张表,我们是可以直接⽤的,如下:如下是实例(都是亲⼿实践过的):1.在表Student中建⽴删除触发器,实现表Student和表SC的级联删除,也就是只要删除表Student中的元组学号为s1,则表SC中SNO为s1的元组也要删除;建⽴完触发器后⽤企业管理器删除Student中学号为30的元组,看看表SC中SNO为30的选课记录是否也⼀起删除;create trigger t_std2 on studentinstead of deleteasbegindeclare @id char(5)select @id=sno from deleteddelete from sc where SNo =@iddelete from student where SNo=@idendgodelete from Student where SNo='00002'/*2. 在表Course中增加⼀个职业规划选修课,为(005,职业规划,4,0014),在表SC中建⽴⼀个触发器,实现规定年龄24岁以上(包括24岁)的学⽣才能选修职业规划这门课程,如果年龄⼩于24岁,则输出’年龄⼩于24,不能选修该门课程’,插⼊失败,⽤SQL语句在SC表中分别插⼊(‘00001’,’005’,null)和(‘00005’,’005’,null)看看结果;**/create trigger t_sc on scfor insertasbegindeclare @id char(5)select @id=sno from insertedif((select cno from inserted)='005' and (select sage from student where SNo= @id )<24)beginprint '年龄⼩于24,不能选修该门课程 'rollback transactionendelseprint 'nice!'endinsert into course values('005','职业规划','4','0014')insert into sc values('00001','005',null)insert into sc values('00005','005',null)select * from scgo3.在表SC中建⽴更改触发器,实现表SC中的修改后的成绩不能低于修改前的成绩,如果修改后的成绩低于修改前的成绩,则输出’修改后的成绩⽐修改前低,不能修改’,修改失败,⽤SQL语句把学号为00001,课程号为001的成绩分别改为90和70,看看结果;createtrigger t2_sc on scafter updateasif(update(score))begindeclare @score1 numeric(3,1),@score2numeric(3,1)select @score1=score from insertedselect @score2=score from deletedif(@score1>@score2 )print 'nice! 'elseupdate scset sc.Score=@score2 from sc,deletedwhere sc.SNo=deleted.SNo o=oprint '失败'endupdate scsetScore=70 where SNo='00001' and CNo='001'4. 在表Teacher中创建触发器,实现如果更新了表Teacher中的年龄和⼯资,则输出’更新了年龄和⼯资’,如果更新了年龄没有更新⼯资,则输出’更新了年龄’,如果更新了⼯资⽽没有更新年龄,则输出’更新了⼯资’,创建完后使⽤SQL语句把tno为001的年龄加1,把tno为002的⼯资加1,把tno为003的年龄和⼯资都加1,看看结果;create trigger t_teacher on teacherafter updateasbegindeclare @age int,@sal floatselect @age=age from deletedselect @sal=sal from deletedif(@age <> (select age from inserted )and @sal <>(select sal from inserted))print '更新了年龄和⼯资 'else if(@age <> (select age from inserted )and @sal =(select sal from inserted))print '更新了⼯资 'else if(@age = (select age from inserted )and @sal <>(select sal from inserted))print '更新了年龄 'endupdate Teacherset age=age+1 where Tno='0001'**//**5. 在不删除触发器的前提下,使3创建的触发器⽆效;alter table teacher disable trigger t_teacher**//**6. 创建⼀个名为tri_Delete_C的触发器,要求⾸先判断数据库中是否已经存在名为tri_Delete_C的触发器,如果存在,⾸先删除,再创建,触发器要求删除⼀门课程时候,⾸先判断该课程有否有⼈选,如果有⼈选,则不能删除,并通过测试数据验证该触发器的执⾏情况。

SQL触发器实例

SQL触发器实例

SQL触发器实例16.2.3 INSERT触发器实例1 创建INSERT触发器为STUDENT表创建触发器S_insert,当向STUDENT表中插入数据时,要求学号必须以“97”开头,且课程号CNO必须在COURSE表中,否则取消插入操作。

实例代码如下。

CREATE TRIGGER S_insertON STUDENTFOR INSERT ASDECLARE @S_no V ARCHAR(4), @S_cno INTSELECT @S_no= SNO, @S_cno=CNOFROM INSERTEDIF (LEFT(@S_no,2)!='97')BEGINROLLBACK TRANSACTIONRAISERROR('输入的学号:%s不是97级的学生,请确认后重新录入!',16,1, @S_no)ENDIF(@S_cno NOT IN (SELECT CNO FROM COURSE))BEGINROLLBACK TRANSACTIONRAISERROR('输入的课程号:%d在COURSE表中不存在,请确认后重新录入!',16,1, @S_cno) END当通过如下语句向STUDENT表中插入数据时:INSERT INTO STUDENT V ALUES('9602','王永','机械工程','男',2,76,'必修')由于插入数据的学号为“9602”,并不是以“97”开头,所以执行S_insert触发器时,将执行“ROLLBACK TRANSACTION”语句,取消完成的工作,并执行RAISERROR语句给出错误信息。

运行结果如下。

输入的学号:9602不是97级的学生,请确认后重新录入!当通过如下语句向STUDENT表中插入数据时:INSERT INTO STUDENT V ALUES('9702','王永','机械工程','男',12,76,'必修')由于课程号12在COURSE表中不存在,所以执行S_insert触发器时,将执行“ROLLBACK TRANSACTION”语句,取消工作,并执行RAISERROR语句给出错误信息。

sql触发器实例

sql触发器实例

sql触发器实例触发器(Trigger)是数据库管理系统(DBMS)中的一种规则,它会在指定的数据库表发生特定事件(如插入、更新或删除)时自动执行。

下面我将为你展示一个简单的SQL 触发器示例。

示例场景假设我们有一个名为employees的表,用于存储员工信息,包括id, name, 和salary。

我们想创建一个触发器,确保每当有新员工添加时,他们的工资不能超过某个特定的值。

1.创建employees 表sqlCREATE TABLE employees (id INT PRIMARY KEY,name VARCHAR(100),salary DECIMAL(10, 2));2.创建触发器我们创建一个名为check_salary的触发器,当在employees表中插入新记录时,它会检查工资是否超过了5000。

如果超过了,触发器将中止插入操作。

sqlDELIMITER //CREATE TRIGGER check_salary BEFORE INSERT ON employeesFOR EACH ROWBEGINIF NEW.salary > 5000THENSIGNAL SQLSTATE'45000'SET MESSAGE_TEXT = 'Salary exceeds maximum limit';END IF;END;//DELIMITER ;在这个触发器中:•BEFORE INSERT ON employees指定了触发器是在向employees表插入新记录之前触发。

•FOR EACH ROW表示这个触发器会对插入操作中的每一行单独触发。

•IF NEW.salary > 5000检查即将插入的新记录的工资是否超过5000。

•SIGNAL SQLSTATE '45000'在工资超过限制时发出一个错误信号,中止插入操作。

3.测试触发器现在我们尝试插入一些记录来测试触发器的功能。

数据库课件SQL-触发器

数据库课件SQL-触发器

CREATE TRIGGER trigger_name ON { table | view } { {{FOR|AFTER|INSTEADOF}{[INSERT][,][UPDATE][,][ DELETE] } AS [ { IF UPDATE ( column ) [ { AND | OR } UPDATE ( column ) ] [ ...n ] | IF ( COLUMNS_UPDATED ( ) { bitwise_operator } updated_bitmask ) { comparison_operator } column_bitmask [ ...n ] }] sql_statement [ ...n ] } }
触发器(TRIGGER) 触发器(TRIGGER)
触发器是一种特殊类型的存储过程, 触发器是一种特殊类型的存储过程,一种与 存储过程 数据表紧密关联的特殊的存储过程, 数据表紧密关联的特殊的存储过程,当该数 据表有插入( )、更改 据表有插入(INSERT)、更改(UPDATE) )、更改( ) 或删除(DELETE)事件发生时,所设置的 或删除( )事件发生时, 触发器就会自动被执行。 与一般意义上的存储过程不同, 与一般意义上的存储过程不同,触发器可以 说是当触发器表内容被更改时自动执行的存 储过也不能传递或接 受参数 帮助我们更好的维护数据库中数据的完整性
Deleted逻辑表 Deleted逻辑表
在学生表中建立删除触发器tr_deleteS,该触发器 , 在学生表中建立删除触发器 在删除学生表中的记录时触发, 在删除学生表中的记录时触发,将从与选课表中相 应学生记录删除。 应学生记录删除。 create trigger tr_deleteS on student after delete as delete from sc where sno in (select sno from deleted)

SQL触发器(有同步update的例子)

SQL触发器(有同步update的例子)

SQL触发器(有同步update的例子)触发器分为:DML触发器、DDL触发器、登录触发器原理如表格所示对表的操作inserted表deleted表增加记录(insert)存放增加的记录无删除记录(delete)无存放被删除的记录修改记录(update)存放更新后的记录存放更新前的记录insert:当对表进行INSERT操作时,INSERT触发器被激发,新的数据行被添加到创建触发器的表和Inserted表。

delete:先将要删除的记录存放在Deleted表里,然后把数据表里的记录删除,再激活After触发器,执行After触发器里的SQL语句。

执行完毕之后,删除内存中的Deleted表,操作结束。

update :生成新的记录到Inserted表,复制旧的记录到Deleted表,然后删除修改表里的旧的记录并写入新纪录。

update例子:创建触发器trigger_2,实现当修改“学生表”中的某个学生的学号时,对应“学生作业表”中的学号也作修改。

use studygocreate trigger trigger_2on studentfor updateasif update(stdid)beginupdate swset stdid = inserted.stdidfrom sw ,deleted,insertedwhere sw.stdid = deleted.stdidendgo查看student表的触发器exec sp_helptrigger 'student'查看trigger_2触发器的定义文本EXEC sp_helptext 'trigger_2'删除student表的trigger_2触发器drop trigger trigger_2修改DML触发器的语法格式如下:ALTER TRIGGER schema_name.trigger_nameON ( table | view )[ WITH ENCRYPTION ]{ FOR | AFTER | INSTEAD OF }{ [ DELETE ] [ , ] [ INSERT ] [ , ] [ UPDATE] }AS sql_statement [ ; ]修改DDL触发器的语法格式如下:ALTER TRIGGER trigger_nameON { ALL SERVER | DATABASE }[ WITH ENCRYPTION ]{ FOR | AFTER } { event_type | event_group } [ ,...n ] AS sql_statement [ ; ]使触发器无效:DISABLE TRIGGER { [ schema.] trigger_name [ ,...n ] | ALL }ON object_name使触发器有效:ENABLE TRIGGER {[schema_name.] trigger_name [ ,...n ] | ALL }ON object name记录数据库的网课学习。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

SQL触发器全过程
第一、概述
一:触发器是一种特殊的存储过程,它不能被显式地调用,而是在往表中插入记录﹑更新记录或者删除记录时被自动地激活。

所以触发器可以用来实现对表实施复杂的完整性约`束。

二: SQL Server为每个触发器都创建了两个专用表:Inserted表和Deleted 表。

这两个表由系统来维护,它们存在于内存中而不是在数据库中。

这两个表的结构总是与被该触发器作用的表的结构相同。

触发器执行完成后,与该触发器相关的这两个表也被删除。

Deleted表存放由于执行Delete或Update语句而要从表中删除的所有行。

Inserted表存放由于执行Insert或Update语句而要向表中插入的所有行。

三:instead of 和 After触发器
SQL Server2000提供了两种触发器:Instead of 和After 触发器。

这两种触发器的差别在于他们被激活的同:
Instead of触发器用于替代引起触发器执行的T-SQL语句。

除表之外,Instead of 触发器也可以用于视图,用来扩展视图可以支持的更新操作。

After触发器在一个Insert,Update或Deleted语句之后执行,进行约束检查等动作都在After触发器被激活之前发生。

After触发器只能用于表。

一个表或视图的每一个修改动作(insert,update和delete)都可以有一个instead of 触发器,一个表的每个修改动作都可以有多个After触发器。

四:触发器的执行过程
如果一个Insert﹑update或者delete语句违反了约束,那幺After触发器不会执行,因为对约束的检查是在After触发器被激动之前发生的。

所以After 触发器不能超越约束。

Instead of 触发器可以取代激发它的操作来执行。

它在Inserted表和Deleted表刚刚建立,其它任何操作还没有发生时被执行。

因为Instead of 触发器在约束之前执行,所以它可以对约束进行一些预处理。

五:使用T-SQL语句来创建触发器
基本语句如下:
create trigger trigger_name
on {table_name | view_name}
{for | After | Instead of }
[ insert, update,delete ]
as
sql_statement
六:删除触发器:
基本语句如下:
drop trigger trigger_name
七:查看数据库中已有触发器:
-- 查看数据库已有触发器
use jxcSoftware
go
select * from sysobjects where xtype='TR'
-- 查看单个触发器
exec sp_helptext '触发器名'
八:修改触发器:
基本语句如下:
alter trigger trigger_name
on {table_name | view_name}
{for | After | Instead of }
[ insert, update,delete ]
as
sql_statement
第二、举例
九:相关示例:
1:在Orders表中建立触发器,当向Orders表中插入一条订单记录时,检查goods表的货品状态status是否为1(正在整理),是,则不能往Orders表加入该订单。

create trigger orderinsert
on orders
after insert
as
if (select status from goods,inserted
where =inserted.goodsname)=1
begin
print 'the goods is being processed'
print 'the order cannot be committed'
rollback transaction --回滚,避免加入
end
2:在Orders表建立一个插入触发器,在添加一条订单时,减少Goods表相应的货品记录中的库存。

create trigger orderinsert1
on orders
after insert
as
if (select status from goods,inserted
where =inserted.goodsname)=1
begin
print 'the goods is being processed'
print 'the order cannot be committed'
rollback transaction --回滚,避免加入
end
3:在Orders表建立一个插入触发器,在添加一条订单时,减少Goods表相应的货品记录中的库存。

create trigger orderinsert1
on orders
after insert
as
update goods set storage=storage-inserted.quantity
from goods,inserted
where
=inserted.goodsname
4:在Goods表建立删除触发器,实现Goods表和Orders表的级联删除。

create trigger goodsdelete
on goods
after delete
as
delete from orders
where goodsname in
(select name from deleted)
5:在Orders表建立一个更新触发器,监视Orders表的订单日期(OrderDate)列,使其不能手工修改.
create trigger orderdateupdate
on orders
after update
as
if update(orderdate)
begin
raiserror(' orderdate cannot be modified',10,1)
rollback transaction
end
6:在Orders表建立一个插入触发器,保证向Orders表插入的货品名必须要在Goods表中一定存在。

create trigger orderinsert3
on orders
after insert
as
if (select count(*) from goods,inserted where
=inserted.goodsname)=0
begin
print ' no entry in goods for this order'
rollback transaction
end
7:Orders表建立一个插入触发器,保证向Orders表插入的货品信息要在Order表中添加
alter trigger addOrder
on Orders
for insert
as
insert into Order
select inserted.Id, inserted.goodName,inserted.Number from inserted。

相关文档
最新文档