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菜鸟入门级教程之触发器本人水平有限,写此博客只为给那些像我一样的菜鸟一点小小的帮助,还请各位大牛不要见笑。
数据库的重要性就不用我多说了吧,我们做的大多数项目都要跟数据库打交道。
因此,熟练掌握数据库的各种操作,就成了一个程序员必备的技能。
今天我们就来简单说一下触发器。
触发器简介:触发器(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触发器实例
--建立触发器,显示修改人数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触发器(附有实例)触发器:即当发⽣某⼀事件时,如果满⾜给定条件,则执⾏相应的动作。
它的基本架构:触发器创建语法:(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触发器实例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触发器实例触发器(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-触发器
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的例子)触发器分为: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记录数据库的网课学习。
数据库 SQL触发器实例讲解
SQL触发器实例讲解1SQL触发器实例1定义:何为触发器?在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分别表示触发事件的表“旧的一条记录”和“新的一条记录”。
实验6 SQL Server触发器
课程数据库原理及应用_ 实验名称 SQL Server触发器教师审批签字一.实验目的1、理解触发器的作用和工作机制;2、熟练掌握后触发器和替代触发器的区别;3、熟练掌握后触发器和替代触发器的创建。
二.实验内容及要求对CPXS数据库,完成如下任务:1、插入后触发器的设计和触发在产品销售表建立触发器,进行插入操作,保证产品编号与产品表中的对应字段一致,客户编号与客户表中对应字段一致,保证销售表中主键不能重复。
设计触发器的程序流程,注意给出适当的提示信息。
激发触发器(提示,可以先取消主键和外键约束)。
2、删除后出发期的设计和触发在客户表建立触发器,进行删除操作,保证删除客户记录时,查询销售表中相应的记录,如果销售表中没有相应客户的信息,才允许删除。
设计触发器的程序流程,注意给出适当的提示信息。
激发触发器(提示,可以先取消外键约束)。
3、用约束实现触发器对于内容1的功能,单纯使用约束进行实现。
对于内容2,设计约束,实现删除客户记录的同时,级联删除销售表中相应的记录。
4、设计替代类型触发器,通过视图更新多张表。
创建销售视图,包含字段(产品编号,产品名称, 客户编号,客户名称, 销售日期,数量,销售额)。
对视图设计更新操作的替代触发器,更新视图的同时,更新产品、客户、销售三张表。
三.实验过程及结果(实验结果可以是运行画面的抓屏,抓屏图片要尽可能的小。
)1.USE CPXSGOCREATE TRIGGER tri_inserton销售for insertasbegindeclare @cpnum char(6)set @cpnum=(select inserted.产品编号from inserted)declare @cmnum char(6)set @cmnum=(select inserted.客户编号from inserted)if(@cpnum not in(select产品编号from产品))beginprint'插入数据中产品编号和产品表中的不一致,插入失败'print @cpnumrollbackendelse if(@cmnum not in(select客户编号from客户))beginprint'插入数据中客户编号和客户表中的不一致,插入失败'print @cmnumrollbackendelseprint'插入成功!'end验证:insert into销售values('s00002','c0002','2001.02.24',45,33333)2.USE CPXSGOCREATE TRIGGER Tri_Cus_Delon客户for deleteasbegindeclare @cmnum char(6)set @cmnum=(select deleted.客户编号from deleted)if(@cmnum is null)beginprint'该客户不存在,删除失败'endelse if(@cmnum in(select客户编号from销售))beginprint'销售表中存在该用户的记录,删除失败'print'客户编号为'+@cmnumrollbackendelseprint'删除成功'+'客户编号为:'+@cmnumend验证:delete from客户where客户编号='c00001'3.(1)USE CPXSGOCREATE TRIGGER tri_inserton销售for insertasbegindeclare @cpnum char(6)set @cpnum=(select inserted.产品编号from inserted)declare @cmnum char(6)set @cmnum=(select inserted.客户编号from inserted)if(@cpnum not in(select产品编号from产品))beginprint'插入数据中产品编号和产品表中的不一致,插入失败'print @cpnumrollbackendelse if(@cmnum not in(select客户编号from客户))beginprint'插入数据中客户编号和客户表中的不一致,插入失败'print @cmnumrollbackendelseprint'插入成功!'end验证:insert into销售values('s00002','c0002','2001.02.24',45,33333)(2)USE CPXSGOCREATE TRIGGER tri_reson客户for insert,deleteasbegindeclare @cmnum char(6)set @cmnum=(select deleted.客户编号from deleted)if(@cmnum is null)beginprint'该客户不存在,删除失败'endelse if(@cmnum in(select客户编号from销售))beginprint'销售表中存在该用户的记录,级联删除销售表中数据'print'客户编号为'+@cmnumdelete from销售where客户编号=@cmnumendelseprint'删除成功'+'客户编号为:'+@cmnumend验证:delete from客户where客户编号='c00001'select*from客户select*from销售4.USE CPXSGOCREATE VIEW view_sellASSELECT A.产品编号,A.产品名称,B.客户编号,B.客户名称,C.销售日期,C.数量,c.销售额FROM dbo.产品 A,dbo.客户 B,dbo.销售 CWHERE A.产品编号=C.产品编号AND B.客户编号=C.客户编号create trigger tri_tidaion view_sellinstead of updateasSET NOCOUNT ONdeclare @cp_num_in char(6)set @cp_num_in=(select inserted.产品编号from inserted)declare @cp_num_del char(6)set @cp_num_del=(select deleted.产品编号from deleted)declare @cp_name_in varchar(30)set @cp_name_in=(select inserted.产品名称from inserted)declare @cp_name_del varchar(30)set @cp_name_del=(select deleted.产品名称from deleted)declare @cm_num_in char(6)set @cm_num_in=(select inserted.客户编号from inserted)declare @cm_num_del char(6)set @cm_num_del=(select deleted.客户编号from deleted)declare @cm_name_in varchar(30)set @cm_name_in=(select inserted.客户名称from inserted)declare @cm_name_del varchar(30)set @cm_name_del=(select deleted.客户名称from deleted)declare @date datetimeset @date=(select inserted.销售日期from inserted)declare @amount intset @amount=(select inserted.数量from inserted)declare @sale decimalset @sale=(select inserted.销售额from inserted)update产品set产品名称=@cp_name_inwhere产品名称=@cp_name_delupdate产品set产品编号=@cp_num_inwhere产品编号=@cp_num_delupdate客户set客户编号=@cm_num_inwhere客户编号=@cm_num_delupdate客户set客户名称=@cm_name_inwhere客户名称=@cm_name_delupdate销售set销售日期=@date,数量=@amount,销售额=@salewhere产品编号=@cp_num_del and客户编号=@cm_num_del 验证:update view_sell set客户名称='客户M',产品名称='iPhone4s',销售日期='',数量=2,销售额='10000'where产品编号='s00001'and客户编号='c00002'select*from dbo.view_sellorder by产品编号select*from dbo.产品order by产品编号select*from dbo.客户order by客户编号select*from dbo.销售order by产品编号四.实验中的问题及心得经过这次试验让我更深入的了解到触发器的用途以及触发器的使用,刚开始不知道从何出下手,最后查书才搞明白如何解决,通过努力解决这几道题,让我明白如何实现触发器的定义,以及对一些事件的处理过程,如何对表和视图进行创建触发器,以及如何完成相关的级联操作,虽然花费了不少时间,但很有收获。
SQLServer-触发器使用实例
SQLServer-触发器使用实例SQLServer 触发器使用实例触发器是一个特殊的存储过程。
常见的有三种:分别应用于Insert , Update , Delete 事件。
一、Trigger语法:create trigger tr_nameon table/view{for | after | instead of } [update][,][insert][,][delete] [with encryption]as {batch | if update (col_name) [{and|or} update (col_name)] } 说明:1 tr_name :名称2 on table/view :触发器所作用的表。
一个触发器只能作用于一个表3 for 和after :同义4 after 与instead of :sql 2000新增项目afrer 与 instead of 的区别After在触发事件发生以后才被激活,只可以建立在表上Instead of代替了相应的触发事件而被执行,既可以建立在表上也可以建立在视图上Inserted临时表Where br.StudentID=d.StudentIDend理解触发器里面的两个临时的表:Deleted , Inserted 。
注意Deleted 与Inserted分别表示触发事件的表“旧的一条记录”和“新的一条记录”。
一个数据库系统中有两个虚拟表用于存储在表中记录改动的信息,分别是:| 虚拟表Inserted | 虚拟表Deleted 在表记录新增时| 存放新增的记录 | 不存储记录修改时 | 存放用来更新的新记录 | 存放更新前的记录删除时| 不存储记录| 存放被删除的记录一个Update 的过程可以看作为:生成新的记录到Inserted表,复制旧的记录到Deleted表,然后删除Student记录并写入新纪录。
对于2,创建一个Delete触发器Create trigger trdStudentOn Studentfor DeleteAsDelete BorrowRecordFrom BorrowRecord br , Delted dWhere br.StudentID=d.StudentID对于3,创建一个Insert触发器create Trigger testdbon myStudentfor insertasbegininsert into BorrowRecord(StudentID,Sex) select studentid,username from inserted myStudentend从这两个例子我们可以看到了触发器的关键:A.2个临时的表;B.触发机制。
sql触发器实例
sql触发器实例(原创版)目录1.SQL 触发器的概念和作用2.SQL 触发器的分类3.SQL 触发器的实例4.SQL 触发器实例的应用场景5.总结正文1.SQL 触发器的概念和作用SQL 触发器是一种与表相关的预定义 SQL 操作,当在表中执行INSERT、UPDATE 或 DELETE 操作时,会自动执行相应的触发器。
触发器可以帮助我们实现一些数据操作的自动化处理,比如数据校验、数据备份等。
2.SQL 触发器的分类SQL 触发器主要分为两类:INSERT 触发器和 UPDATE 触发器。
INSERT 触发器是在向表中插入数据时执行的,而 UPDATE 触发器是在更新表中数据时执行的。
3.SQL 触发器的实例下面以 MySQL 数据库为例,给出一个 INSERT 触发器的实例:假设我们有一个名为“students”的表,包含以下字段:id、name、age、score。
现在,我们希望在向该表插入新数据时,自动更新学生的平均分数。
可以创建一个 INSERT 触发器,如下所示:```sqlCREATE TRIGGER update_average_scoreAFTER INSERTON students FOR EACH ROWBEGINUPDATE studentsSET score = score + NEW.scoreWHERE id = NEW.id;END;```在这个例子中,当向 students 表中插入新数据时,会自动执行update_average_score 触发器。
触发器会根据新插入的数据,更新学生的平均分数。
4.SQL 触发器实例的应用场景SQL 触发器实例可以应用于以下场景:- 数据校验:在数据插入或更新时,对数据进行合法性校验,确保数据的正确性。
- 数据备份:在数据更新时,将更新前的数据备份到另一个表或文件中,以便后续恢复数据。
- 数据统计:在数据插入或更新时,对数据进行统计分析,如计算平均值、求和等。
sql触发器实例
sql触发器实例摘要:1.SQL 触发器的概念2.SQL 触发器的分类3.SQL 触发器的实例4.SQL 触发器的作用5.SQL 触发器的使用注意事项正文:1.SQL 触发器的概念SQL 触发器是一种在对数据库中的表执行某些操作(如插入、更新或删除数据)时自动执行的存储过程。
它可以在数据表发生变更时,自动地更新其他相关表的数据,或者执行一些特定的操作,如日志记录、数据验证等。
2.SQL 触发器的分类SQL 触发器主要分为两类:(1)INSERT 触发器:在向表中插入数据时自动执行的触发器。
(2)UPDATE/DELETE 触发器:在更新或删除表中数据时自动执行的触发器。
3.SQL 触发器的实例假设有一个名为“订单”的表(order),包含以下字段:订单号(order_id)、客户名(customer_name)、订单日期(order_date)和订单状态(order_status)。
当更新订单状态时,希望将订单日期更新为当前日期。
可以使用以下方法创建一个UPDATE 触发器:```sqlCREATE TRIGGER update_order_dateAFTER UPDATE ON orderFOR EACH ROWBEGINSET NEW.order_date = NOW();END;```在这个实例中,当更新订单表中的数据时,触发器将自动更新订单日期为当前日期。
4.SQL 触发器的作用SQL 触发器的主要作用有以下几点:(1)数据一致性:确保数据库中数据的一致性,如在更新订单表时自动更新其他相关表的数据。
(2)数据验证:在数据插入、更新或删除之前进行数据验证,确保数据的合法性。
(3)日志记录:记录数据库操作日志,便于追踪和审计。
(4)性能优化:减少应用程序中的重复代码,提高执行效率。
5.SQL 触发器的使用注意事项(1)避免循环引用:在使用触发器时,需要注意避免触发器之间的循环引用,否则可能导致数据库无限循环执行。
数据库开发-sql server触发器如何使用实例解析
数据库开发-sql server触发器如何使用实例解析数据库开发-sql server触发器如何使用实例解析在数据库开发中,触发器是一种特殊的存储过程,它会在数据库表发生特定事件时自动执行。
触发器可以帮助我们实现数据的自动化处理和一些复杂的业务逻辑。
在本文中,我将详细介绍SQL Server触发器的使用实例,以帮助您更好理解和应用这一重要的数据库开发技术。
1. 触发器的基本概念在开始之前,让我们先来了解一下触发器的基本概念。
触发器是一种特殊的存储过程,它与数据库表相关联,并在表发生特定事件时自动执行。
这些特定事件包括INSERT、UPDATE和DELETE操作。
触发器可以在数据被修改之前或之后执行,这取决于触发器的类型,分为BEFORE和AFTER两种。
2. SQL Server触发器的创建在SQL Server中,我们可以使用CREATE TRIGGER语句来创建触发器。
以下是一个简单的创建触发器的示例:```sqlCREATE TRIGGER [触发器名称]ON [表名]FOR INSERT, UPDATE, DELETEASBEGIN-- 触发器的逻辑代码END```在上面的示例中,[触发器名称]表示触发器的名称,[表名]表示要关联的数据库表,FOR子句指定了触发器要响应的事件类型,AS子句中包含了触发器的逻辑代码。
3. 触发器的使用实例现在让我们来看一个实际的使用实例,假设我们有一个名为Student的表,其中包含了学生的尊称和芳龄信息。
我们想要在插入新的学生信息时,自动向另外一个名为StudentLog的表中插入一条日志信息,以便记录学生信息的变更历史。
我们可以通过触发器来实现这一功能。
```sqlCREATE TRIGGER trgAfterInsertON StudentAFTER INSERTASBEGININSERT INTO StudentLog (操作类型, 学生尊称, 操作时间)SELECT '新增', inserted.尊称, GETDATE()FROM insertedEND```在上面的示例中,我们创建了一个AFTER INSERT类型的触发器,当向Student表中插入新记录时,触发器会自动执行并向StudentLog 表中插入一条日志信息。
sql触发器实例
SQL触发器实例1. 什么是SQL触发器?在SQL中,触发器(Trigger)是一种特殊的存储过程,它会在指定的数据库操作(如插入、更新、删除)发生时自动执行。
触发器可以用于实现复杂的业务逻辑和数据完整性约束。
触发器通常与表相关联,当表上的指定操作被执行时,触发器会自动触发并执行相应的代码逻辑。
2. 触发器的语法下面是一个简单的创建触发器的语法:CREATE TRIGGER trigger_name{BEFORE | AFTER} {INSERT | UPDATE | DELETE}ON table_nameFOR EACH ROWBEGIN-- 触发器执行的代码逻辑END;其中: - trigger_name是触发器的名称,需要在数据库中唯一。
- BEFORE或AFTER指定了触发器执行的时间点,分别在操作之前或之后。
- INSERT、UPDATE或DELETE指定了要监视和响应的数据库操作类型。
- table_name是与触发器相关联的表名。
- FOR EACH ROW表示对每一行数据都会执行相应代码块。
3. 触发器示例3.1 在插入数据时更新相关表假设我们有两个表:用户表(users)和订单表(orders)。
当向订单表插入一条新记录时,我们希望自动更新用户表中的订单数量字段。
首先,我们创建一个触发器来实现这个逻辑:CREATE TRIGGER update_order_countAFTER INSERT ON ordersFOR EACH ROWBEGINUPDATE users SET order_count = order_count + 1 WHERE id = er_id; END;在上述触发器中,我们指定了在orders表上插入数据之后执行触发器逻辑。
每当插入一条新记录时,触发器会自动执行一个SQL语句来更新对应用户的订单数量。
3.2 在删除数据时进行级联操作假设我们有两个表:部门表(departments)和员工表(employees)。
SQLServer触发器实例详解
SQLServer触发器实例详解Microsoft SQL Server™ 2000 提供了两种主要机制来强制业务规则和数据完整性:约束和触发器。
触发器是⼀种特殊类型的存储过程,它不同于之前的我们介绍的存储过程。
触发器主要是通过事件进⾏触发被⾃动调⽤执⾏的。
⽽存储过程可以通过存储过程的名称被调⽤。
Ø 什么是触发器触发器对表进⾏插⼊、更新、删除的时候会⾃动执⾏的特殊存储过程。
触发器⼀般⽤在check约束更加复杂的约束上⾯。
触发器和普通的存储过程的区别是:触发器是当对某⼀个表进⾏操作。
诸如:update、insert、delete这些操作的时候,系统会⾃动调⽤执⾏该表上对应的触发器。
SQL Server 2005中触发器可以分为两类:DML触发器和DDL触发器,其中DDL触发器它们会影响多种数据定义语⾔语句⽽激发,这些语句有create、alter、drop语句。
优点触发器可通过数据库中的相关表实现级联更改;通过级联引⽤完整性约束可以更有效地执⾏这些更改。
触发器可以强制⽐⽤ CHECK 约束定义的约束更为复杂的约束。
与 CHECK 约束不同,触发器可以引⽤其它表中的列。
例如,触发器可以使⽤另⼀个表中的 SELECT ⽐较插⼊或更新的数据,以及执⾏其它操作,如修改数据或显⽰⽤户定义错误信息。
触发器也可以评估数据修改前后的表状态,并根据其差异采取对策。
DML触发器分为:1、 after触发器(之后触发)a、 insert触发器b、 update触发器c、 delete触发器2、 instead of 触发器(之前触发)其中after触发器要求只有执⾏某⼀操作insert、update、delete之后触发器才被触发,且只能定义在表上。
⽽instead of触发器表⽰并不执⾏其定义的操作(insert、update、delete)⽽仅是执⾏触发器本⾝。
既可以在表上定义instead of触发器,也可以在视图上定义。
SqlServer触发器的原理及案例
SqlServer触发器的原理及案例合理的选用触发器会让你的系统更高效2010Ssc目录第1章何为触发器 (3)1.1 触发器的'本质' (3)1.2 这样做带来的'功能': (3)1.3 触发器的作用 (3)1.4 说明: (3)第2章对触发器3种操作的分析 (4)2.1 创建触发器 (4)2.2 学习案例 (5)2.2.1 建立表 (5)2.2.2 触发器练习1 (5)2.2.3 触发器练习2: (6)第3章图形化操作触发器 (7)3.1 查看触发器情况 (7)第4章触发器中的变量操作 (11)第5章SQL触发器语法参考 (11)第1章何为触发器1.1触发器的'本质'触发器是一种特殊的存储过程,它不能被显式地调用,而是在往表中插入记录、更改记录或者删除记录时,当事件发生时,才被自动地激活。
1.2这样做带来的'功能':触发器可以用来对表实施复杂的完整性约束,保持数据的一致性,当触发器所保护的数据发生改变时,触发器会自动被激活,响应同时执行一定的操作(对其它相关表的操作),从而保证对数据的不完整性约束或不正确的修改。
触发器可以查询其它表,同时也可以执行复杂的T-SQL语句。
触发器和引发触发器执行的命令被当作一次事务处理,因此就具备了事务的所有特征。
注意:'事务具备什么特征?在触发器中的作用?'如果发现引起触发器执行的T-SQL语句执行了一个非法操作,比如关于其它表的相关性操作,发现数据丢失或需调用的数据不存在,那么就回滚到该事件执行前的SQL SERVER数据库状态。
1.3触发器的作用触发器可以对数据库进行级联修改,这一点刚才已经说过了。
需要说明的是:'触发器和约束的关系和区别'(1)一般来说,使用约束比使用触发器效率更高。
(2)同时,触发器可以完成比CHECK约束更复杂的限制。
1.4说明:1.与CHECK约束不同,在触发器中可以引用其它的表。
SQL触发器实例
SQL触发器实例之迟辟智美创作界说:何为触发器?在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分别暗示触发事件的表“旧的一条记录”和“新的一条记录”.一个数据库系统中有两个虚拟表用于存储在表中记录改动的信息,分别是:虚拟表Inserted 虚拟表Deleted在表记录新增时寄存新增的记录不存储记录修改时寄存用来更新的新记录寄存更新前的记录删除时不存储记录寄存被删除的记录一个Update 的过程可以看作为:生成新的记录到Inserted表,复制旧的记录到Deleted表,然后删除Student记录并写入新纪录.对2,创立一个Delete触发器Create trigger trdStudentOn Studentfor DeleteAsDelete BorrowRecordFrom BorrowRecord br , Delted dWhere br.StudentID=d.StudentID从这两个例子我们可以看到了触发器的关键:A.2个临时的表;B.触发机制.SQL触发器实例2/*建立虚拟测试环境,包括:表[卷烟库存表],表[卷烟销售表].请年夜家注意跟踪这两个表的数据,体会触发器究竟执行了什么业务逻辑,对数据有什么影响.为了能更清晰的表述触发器的作用,表结构存在数据冗余,且不符合第三范式,这里特此说明.*/USE MasterGOIF EXISTS (SELECT NAME FROM SYSOBJECTS WHERE XTYPE = ’U’ AND NAME = ’卷烟库存表’)DROP TABLE 卷烟库存表GOIF EXISTS (SELECT NAME FROM SYSOBJECTS WHERE XTYPE = ’U’ AND NAME = ’卷烟销售表’)DROP TABLE 卷烟销售表GO--业务规则:销售金额 = 销售数量 * 销售单价业务规则.CREATE TABLE 卷烟销售表(卷烟品牌 V ARCHAR(40) PRIMARY KEY NOT NULL,购货商 V ARCHAR(40) NULL,销售数量 INT NULL,销售单价 MONEY NULL,销售金额 MONEY NULL)GO--业务规则:库存金额 = 库存数量 * 库存单价业务规则.CREATE TABLE 卷烟库存表(卷烟品牌 V ARCHAR(40) PRIMARY KEY NOT NULL,库存数量 INT NULL,库存单价 MONEY NULL,库存金额 MONEY NULL)GO--创立触发器,示例1/*创立触发器[T_INSERT_卷烟库存表],这个触发器较简单.说明:每当[卷烟库存表]发生 INSERT 举措,则引发该触发器.触发器功能:强制执行业务规则,保证拔出的数据中,库存金额 = 库存数量 * 库存单价.注意: [INSERTED]、[DELETED]为系统表,不成创立、修改、删除,但可以调用.重要:这两个系统表的结构同拔出数据的表的结构.*/IF EXISTS (SELECT NAME FROM SYSOBJECTS WHERE XTYPE = ’TR’ AND NAME = ’T_INSERT_卷烟库存表’) DROP TRIGGER T_INSERT_卷烟库存表GOCREATE TRIGGER T_INSERT_卷烟库存表ON 卷烟库存表FOR INSERTAS--提交事务处置BEGIN TRANSACTION--强制执行下列语句,保证业务规则UPDA TE 卷烟库存表SET 库存金额 = 库存数量 * 库存单价WHERE 卷烟品牌 IN (SELECT 卷烟品牌 from INSERTED)COMMIT TRANSACTIONGO/*针对[卷烟库存表],拔出测试数据:注意,第一条数据(红塔山新势力)中的数据符合业务规则,第二条数据(红塔山人为峰)中,[库存金额]空,不符合业务规则,第三条数据(云南映像)中,[库存金额]不即是[库存数量]乘以[库存单价],不符合业务规则.第四条数据库存数量为0.请注意在拔出数据后,检查[卷烟库存表]中的数据是否库存金额 = 库存数量 * 库存单价.*/INSERT INTO 卷烟库存表(卷烟品牌,库存数量,库存单价,库存金额)SELECT ’红塔山新势力’,100,12,1200 UNION ALLSELECT ’红塔山人为峰’,100,22,NULL UNION ALLSELECT ’云南映像’,100,60,500 UNION ALLSELECT ’玉溪’,0,30,0GO--查询数据SELECT * FROM 卷烟库存表GO/*结果集RecordId 卷烟品牌库存数量库存单价库存金额-------- ------------ -------- ------- ---------1 红塔山新势力 100 12.0000 1200.00002 红塔山人为峰 100 22.0000 2200.00003 云南映像 100 60.0000 6000.00004 玉溪 0 30.0000 .0000(所影响的行数为 4 行)*/--触发器示例2/*创立触发器[T_INSERT_卷烟销售表],该触发器较复杂.说明: 每当[卷烟库存表]发生 INSERT 举措,则引发该触发器.触发器功能:实现业务规则.业务规则: 如果销售的卷烟品牌不存在库存或者库存为零,则返回毛病.否则则自动减少[卷烟库存表]中对应品牌卷烟的库存数量和库存金额.*/IF EXISTS (SELECT NAME FROM SYSOBJECTS WHERE XTYPE = ’TR’ AND NAME = ’T_INSERT_卷烟销售表’) DROP TRIGGER T_INSERT_卷烟销售表GOCREATE TRIGGER T_INSERT_卷烟销售表ON 卷烟销售表FOR INSERTASBEGIN TRANSACTION--检查数据的合法性:销售的卷烟是否有库存,或者库存是否年夜于零IF NOT EXISTS (SELECT 库存数量FROM 卷烟库存表WHERE 卷烟品牌 IN (SELECT 卷烟品牌 FROM INSERTED))BEGIN--返回毛病提示RAISERROR(’毛病!该卷烟不存在库存,不能销售.’,16,1)--回滚事务ROLLBACKRETURNENDIF EXISTS (SELECT 库存数量FROM 卷烟库存表WHERE 卷烟品牌 IN (SELECT 卷烟品牌 FROM INSERTED) AND库存数量 <= 0)BEGIN--返回毛病提示RAISERROR(’毛病!该卷烟库存小于即是0,不能销售.’,16,1)--回滚事务ROLLBACKRETURNEND--对合法的数据进行处置--强制执行下列语句,保证业务规则UPDA TE 卷烟销售表SET 销售金额 = 销售数量 * 销售单价WHERE 卷烟品牌 IN (SELECT 卷烟品牌 FROM INSERTED)DECLARE @卷烟品牌 V ARCHAR(40)SET @卷烟品牌 = (SELECT 卷烟品牌 FROM INSERTED)DECLARE @销售数量 MONEYSET @销售数量 = (SELECT 销售数量 FROM INSERTED)UPDA TE 卷烟库存表SET 库存数量 = 库存数量 - @销售数量,库存金额 = (库存数量 - @销售数量)*库存单价WHERE 卷烟品牌 = @卷烟品牌COMMIT TRANSACTIONGO--请年夜家自行跟踪[卷烟库存表]和[卷烟销售表]的数据变动.--针对[卷烟销售表],拔出第一条测试数据,该数据是正常的.INSERT INTO 卷烟销售表(卷烟品牌,购货商,销售数量,销售单价,销售金额)SELECT ’红塔山新势力’,’某购货商’,10,12,1200GO--针对[卷烟销售表],拔出第二条测试数据,该数据销售金额不即是销售单价 * 销售数量.--触发器将自动更正数据,使销售金额即是销售单价 * 销售数量.INSERT INTO 卷烟销售表(卷烟品牌,购货商,销售数量,销售单价,销售金额)SELECT ’红塔山人为峰’,’某购货商’,10,22,2000GO--针对[卷烟销售表],拔出第三条测试数据,该数据中的卷烟品牌在卷烟库存表中找不到对应. --触发器将报错.INSERT INTO 卷烟销售表(卷烟品牌,购货商,销售数量,销售单价,销售金额)SELECT ’红河V8’,’某购货商’,10,60,600GO/*结果集服务器: 消息 50000,级别 16,状态 1,过程 T_INSERT_卷烟销售表,行 15毛病!该卷烟不存在库存,不能销售.*/--针对[卷烟销售表],拔出第三条测试数据,该数据中的卷烟品牌在卷烟库存表中库存为0.--触发器将报错.INSERT INTO 卷烟销售表(卷烟品牌,购货商,销售数量,销售单价,销售金额)SELECT ’玉溪’,’某购货商’,10,30,300GO/*结果集服务器: 消息 50000,级别 16,状态 1,过程 T_INSERT_卷烟销售表,行 29毛病!该卷烟库存小于即是0,不能销售.*/--查询数据SELECT * FROM 卷烟库存表SELECT * FROM 卷烟销售表GO/*弥补:1、本示例主要通过一个简单的业务规则实现来进行触发器使用的说明,具体的要根据需要灵活处置;2、关于触发器要理解并运用好 INSERTED ,DELETED 两个系统表;3、本示例创立的触发器都是 FOR INSERT ,具体的语法可参考://///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////Trigger语法//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////CREATE TRIGGER trigger_nameON { table | view }[ WITH ENCRYPTION ] --用于加密触发器{{ { FOR | AFTER | INSTEAD OF } { [ INSERT ] [ , ] [ UPDA TE ] }[ WITH APPEND ][ NOT FOR REPLICATION ]AS[ { IF UPDATE ( column )[ { AND | OR } UPDA TE ( column ) ][ ...n ]| IF ( COLUMNS_UPDATED ( ) { bitwise_operator } updated_bitmask ){ comparison_operator } column_bitmask [ ...n ]} ]sql_statement [ ...n ]}}4、关于触发器,还应该注意(1)、DELETE 触发器不能捕捉 TRUNCATE TABLE 语句.(2)、触发器中不允许以下 Transact-SQL 语句:ALTER DATABASE CREATE DATABASE DISK INITDISK RESIZE DROP DATABASE LOAD DATABASELOAD LOG RECONFIGURE RESTORE DA TABASERESTORE LOG(3)、触发器最多可以嵌套 32 层.*/--修改触发器--实质上,是将 CREATE TRIGGER ... 修改为 ALTER TRIGGER ...即可.--删除触发器DROP TRIGGER xxxGO--删除测试环境DROP TABLE 卷烟库存表GODROP TABLE 卷烟销售表GODROP TRIGGER T_INSERT_卷烟库存表GODROP TRIGGER T_INSERT_卷烟销售表GO##################################################################触发器的基础知识和例子:create trigger tr_nameon table/view{for | after | instead of } [update][,][insert][,][delete][with encryption]as {batch | if update (col_name) [{and|or} update (col_name)] }说明:1 tr_name :触发器名称2 on table/view :触发器所作用的表.一个触发器只能作用于一个表3 for 和after :同义4 after 与instead of :sql 2000新增项目afrer 与 instead of 的区别After在触发事件发生以后才被激活,只可以建立在表上Instead of取代了相应的触发事件而被执行,既可以建立在表上也可以建立在视图上5 insert、update、delete:激活触发器的三种把持,可以同时执行,也可选其一6 if update (col_name):标明所作的把持对指定列是否有影响,有影响,则激活触发器.另外,因为delete 把持只对行有影响,所以如果使用delete把持就不能用这条语句了(虽然使用也不犯错,可是不能激活触发器,没意义).7 触发器执行时用到的两个特殊表:deleted ,inserteddeleted 和inserted 可以说是一种特殊的临时表,是在进行激活触发器时由系统自动生成的,其结构与触发器作用的表结构是一样的,只是寄存的数据有不同.续下面表格说明deleted 与inserted 数据的不同deleted 与inserted 数据的不同Inserted寄存进行insert和update 把持后的数据Deleted寄存进行delete 和update把持前的数据注意:update 把持相当于先进行delete 再进行insert ,所以在进行update把持时,修改前的数据拷贝一条到deleted 表中,修改后的数据在存到触发器作用的表的同时,也同时生成一条拷贝到insered表中/////////CREATE TRIGGER [TRIGGER admixture_receive_log] ON dbo.chl_lydjFOR UPDA TEASbegindeclare @djsfxg char(10) declare @wtbh char(20)select @wtbh=wtbh from insertedupdate ly_tzk set djsfxg='已修改' where wtbh=@wtbhendif (select data_sfjl from t_logsetup)='是'begindeclare @oldcjmc char (100) declare @oldlyrq datetimedeclare @oldbzbh char (60) declare @oldzl char (20)declare @olddj char (10)declare @newcjmc char (100) declare @newlyrq datetimedeclare @newbzbh char (60) declare @newzl char (20)declare @newdj char (10)declare @xgr char (20)select @oldcjmc=cjmc,@oldlyrq=lyrq,@oldbzbh=bzbh,@oldzl=zl,@olddj=dj from deletedselect @newcjmc=cjmc,@newlyrq=lyrq,@newbzbh=bzbh,@newzl=zl,@newdj=dj from insertedselect @xgr=xgr from t_modifyuser where @wtbh=wtbhif @oldcjmc<>@newcjmcbegininsert into t_modifylog (wtbh, mod_time, mod_table, mod_field, ori_value, now_value, mod_people) values (@wtbh,getdate(), 'chl_lydj','cjmc', @oldcjmc, @newcjmc, @xgr)endend//////////修改时,直接把‘create’改为‘alter’即可/////////////////////////CREATE TRIGGER [TRIGGER ly_tzk_syf] ON dbo.ly_tzkFOR insertASbegindeclare @clmc char(100) declare @dwbh char(100) declare @syf char(100) declare @dwgcbh char(100) declare @wtbh char(50)declare @dj_1 money declare @feiyong_z money declare @feiyong_xf money declare @feiyong_sy money declare @dj char(20)select @wtbh=wtbh , @clmc=clmc , @dwbh=dwbh ,@syf=syf from insertedselect @dj=dj from feihao_bz where clmc=@clmcselect @feiyong_z=feiyong_z, @feiyong_xf=feiyong_xf, @feiyong_sy=feiyong_sy from gongchengxinxi where dwgcbh=@dwbhset @dj_1=convert(money ,@dj)if @dj_1 <>0beginset @feiyong_xf=@feiyong_xf+@dj_1set @feiyong_sy=@feiyong_sy-@dj_1update ly_tzk set syf=@dj where wtbh=@wtbhupdate gongchengxinxi set feiyong_xf=@feiyong_xf, feiyong_sy=@feiyong_sy where dwgcbh=@dwbhendelse update ly_tzk set syf=convert(char , 0.0) where wtbh=@wtbhend//////////////////////CREATE TRIGGER [TRIGGER ly_tzk_syf_shanchu] ON dbo.ly_tzkFOR deleteASbegindeclare @clmc char(100) declare @dwbh char(100) declare @dwgcbh char(100) declare @wtbh char(50)declare @feiyong_z money declare @feiyong_xf money declare @feiyong_sy moneydeclare @syf char(100) declare @syf_1 money--declare @dj char(20) declare @dj_1 moneyselect @wtbh=wtbh , @clmc=clmc , @dwbh=dwbh ,@syf=syf from inserted--select @dj=dj from feihao_bz where clmc=@clmcselect @feiyong_z=feiyong_z, @feiyong_xf=feiyong_xf, @feiyong_sy=feiyong_sy from gongchengxinxi where dwgcbh??@dwbh??set??@syf_ ??convert money??@syf????if??@syf_ ??????begin??set??@feiyong_xf??@feiyong_xf@syf_??set??@feiyong_sy??@feiyong_sy@syf_ ????update??gongchengxinxi??set??feiyong_xf??@feiyong_xf??feiyong_sy??@feiyong_sy??where??dwgcbh??@dwbh?? ??endend。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 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。