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代替了相应的触发事件而被执行,既可以建立在表上也可以建立在视图上5 insert、update、delete:激活触发器的三种操作,可以同时执行,也可选其一6 if update (col_name):表明所作的操作对指定列是否有影响,有影响,则激活触发器。
此外,因为delete 操作只对行有影响,所以如果使用delete操作就不能用这条语句了(虽然使用也不出错,但是不能激活触发器,没意义)。
7 触发器执行时用到的两个特殊表:deleted ,inserteddeleted 和inserted 可以说是一种特殊的临时表,是在进行激活触发器时由系统自动生成的,其结构和触发器作用的表结构是一样的,只是存放的数据有差异。
二、实例:实例1(注意这里的关联,条件是如何关联,update中set的值是和谁关联。
这些都可以从【触发器的两个临时表:inserted、deleted】中得到答案)比如,这么两个表:Create Table Student( --学生表StudentID int primary key, --学号StudentName varchar(50),姓名)Create Table BorrowRecord( --学生借书记录表BorrowRecord int identity(1,1), --流水号StudentID int , --学号BorrowDate datetime, --借出时间ReturnDAte Datetime, --归还时间...)用到的功能有:1.如果我更改了学生的学号,我希望他的借书记录仍然和这个学生相关(也就是同时更改借书记录表的学号);2.如果该学生已经毕业,我希望删除他的学号的同时,也删除它的借书记录。
sqlserver数据库触发器的工作原理

SQL Server数据库触发器是一种特殊类型的存储过程,它可以在数据库中的特定事件发生时自动执行。
触发器可以用于监视数据的变化并采取相应的操作,例如插入、更新或删除数据时触发某些业务逻辑。
本文将深入探讨SQL Server数据库触发器的工作原理,包括触发器的类型、创建和使用方法,以及一些最佳实践。
一、触发器的类型SQL Server中有两种类型的触发器:DML触发器和DDL触发器。
1. DML触发器DML触发器(Data Manipulation Language Trigger)是针对数据操作事件的触发器,包括INSERT、UPDATE和DELETE。
当这些事件发生时,DML触发器可以在受影响的表上自动执行相应的逻辑。
DML 触发器可以分为AFTER触发器和INSTEAD OF触发器。
- AFTER触发器:AFTER触发器在数据操作事件完成后触发,可以用于记录日志、更新其他相关表等操作。
- INSTEAD OF触发器:INSTEAD OF触发器可以代替原始的数据操作事件,允许用户在数据操作前执行自定义的逻辑,常用于数据验证和转换。
2. DDL触发器DDL触发器(Data Definition Language Trigger)用于监视数据库结构的变化,包括CREATE、ALTER和DROP等DDL语句的执行。
DDL触发器可以在这些数据库结构变化发生时执行相应的逻辑,如记录变更、阻止某些操作等。
二、触发器的创建和使用要创建触发器,首先需要使用CREATE TRIGGER语句定义并命名一个新触发器,然后指定触发器在哪些事件上触发,以及触发时执行的逻辑。
触发器逻辑通常是一段T-SQL代码,可以包含查询、条件判断、事务控制等操作。
1. 创建DML触发器要创建DML触发器,可以使用如下语法:```CREATE TRIGGER trigger_nameON table_nameAFTER/INSTEAD OF INSERT/UPDATE/DELETEASBEGIN-- trigger logicEND```在这个语法中,trigger_name是触发器的名称,table_name是触发器所在的表,AFTER/INSTEAD OF INSERT/UPDATE/DELETE指定触发的事件,BEGIN和END之间是触发器的逻辑代码。
sqlserver触发器例题

sqlserver触发器例题SQL Server 触发器是一种数据库对象,它可以在特定表上的数据发生更改时自动执行一系列操作。
触发器可以用于实现业务规则和数据完整性约束,以及跟踪数据变化等功能。
在本文中,我们将介绍两个 SQL Server 触发器的例题及其解决方案。
例题一:在一张名为"Employee"的表上创建一个触发器,以便在插入新员工记录时自动将当前日期作为"hire_date"字段的默认值。
解决方案:首先,我们需要使用下面的 SQL 命令创建一个名为"Employee"的表,并在该表中添加一个"hire_date"字段:```sql CREATE TABLE Employee ( employee_id INT PRIMARY KEY, employee_name VARCHAR(50), hire_date DATE ) ```接下来,我们可以使用下面的 SQL 命令创建一个名为"trg_Employee_Insert"的触发器:```sql CREATE TRIGGER trg_Employee_Insert ON Employee FOR INSERT AS BEGIN UPDATE Employee SET hire_date = GETDATE() WHERE employee_id IN (SELECT employee_id FROM inserted) END ```在这个触发器中,我们使用了"FOR INSERT"来指定触发器在插入操作之后执行。
然后,我们使用了"GETDATE()"函数来获取当前日期,并将其更新到"hire_date"字段中。
现在,当我们向"Employee"表中插入一条新的员工记录时,触发器将自动将当前日期作为"hire_date"字段的默认值:```sql INSERT INTO Employee (employee_id, employee_name) VALUES (1, 'John') ```例题二:在一张名为"Orders"的表上创建一个触发器,以便在删除订单记录时自动将相应的产品库存加回去。
sqlserver 触发器示例

sqlserver 触发器示例1--检查当前触发器是否已存在2IF exists(SELECT*FROM sysobjects WHERE xtype='TR'AND [name]='TR_INSERTUserInfo_LoginLog')3--存在即删除该触发器4DROP TRIGGER TR_INSERTUserInfo_LoginLog5go6--触发器创建在UserInfo表上当对UserInfo表执行INSERT操作后自动执行触发器中的SQL语句7CREATE TRIGGER TR_INSERTUserInfo_LoginLog8ON UserInfo9FOR INSERT10AS11BEGIN12--定义接受新建用户ID的参数13DECLARE@userID VARCHAR(50);14--查询INSERTED临时表获取新建用户ID15SELECT@userID=UserID FROM Inserted16--向用户登录日志表中添加新建用户登录日志17INSERT INTO LoginLog VALUES(@userID,getDate())18END19GO2021IF EXISTS(SELECT*FROM sysobjects WHERE xtype='TR'AND [name]='TR_Update_UserInfo_ManagerLog')22DROP TRIGGER TR_Update_UserInfo_ManagerLog23GO24CREATE TRIGGER TR_Update_UserInfo_ManagerLog25ON UserInfo26FOR UPDATE27AS28--接受被更新用户信息的ID29DECLARE@userId INT30--接受更新前用户密码的变量31DECLARE@oldPwd VARCHAR(50)32--接受更新后用户密码的变量33DECLARE@newPwd VARCHAR(50)34--接受更新前用户邮件的变量35DECLARE@oldEmail VARCHAR(50)36--接受更新后用户邮件的变量37DECLARE@newEmail VARCHAR(50)38--从DELETED临时表中获取数据更新前用户数据39SELECT@userId=UserId,@oldPwd=password,@oldEmail=Em ail FROM Deleted40--从INSERTED临时表中获取数据更新后的用户数据41SELECT@newPwd=password,@newEmail=Email FROM Inserte d42--向系统日志表中插入数据43INSERT INTO managerlog VALUES('修改ID为:['+CAST(@use rId AS VARCHAR(5))+']用户信息:<br/>Password:{'+@oldPwd+'}-->Password:{'+@newPwd+'}<br/>Email:{'+@oldEmail+'}-->{'+@ newEmail+'}',getDate())44Go454647--创建当用户表插入新数据时,添加工资表对应记录的触发器48IF EXISTS(SELECT*FROM sysobjects WHERE[xtype]='TR'AN D[name]='Insert_Emp_EmpPayment')49DROP TRIGGER Insert_Emp_EmpPayment50go51CREATE TRIGGER Insert_Emp_EmpPayment52ON Employee153FOR INSERT54AS55DECLARE@empId INT56SELECT@empId=EmpId FROM Inserted57INSERT INTO EmpPayMent VALUES(@empId,800.00,null) 58go5960--创建当向工资表插入数据时,更新工资表中员工奖金61IF EXISTS(SELECT*FROM sysobjects WHERE[xtype]='TR'AN D[name]='Insert_EmpPayment')62DROP TRIGGER Insert_EmpPayment63go64CREATE TRIGGER Insert_EmpPayment65ON EmpPayMent66FOR INSERT67AS68DECLARE@empId INT69SELECT@empId=EmpId FROM Inserted70UPDATE EmpPayMent SET Bonus=50.00WHERE EmpID=@empId 71go。
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的触发器,如果存在,⾸先删除,再创建,触发器要求删除⼀门课程时候,⾸先判断该课程有否有⼈选,如果有⼈选,则不能删除,并通过测试数据验证该触发器的执⾏情况。
SQLServer2000编程之触发器

李四
1000 0002 20001
检查deleted和inserted表中的数据,确定是 否需要回滚或执行其他操作
UPDATE触发器示例
问题:
跟踪用户的交易,交易金额超过20000元,则取消交易,并 给出错误提示。
分析:
在bank表上创建UPDATE触发器 修改前的数据可以从deleted表中获取 修改后的数据可以从inserted表中获取
inserted 和deleted 表
修改操作
inserted表 deleted表
增加 (INSERT)记 录
存放新增的记 录
------
删除 (DELETE)记 录
-----
存放被删除的 记录
修 (U改PDATinEs)e记rted表存 记和放录d更ele新te后d表的存放存记的放录信更息 新前的
从deleted表中 获取被删除的
交易记录
IF NOT EXISTS(SELECT * FROM sysobjects
WHERE name='backupTable')
SELECT * INTO backupTable FROM deleted
ELSE
INSERT INTO backupTable
SELECT * FROM deleted
帐户信息表bank
张三开户1000元, 李四开户1元
张三取钱200
问题:
交易信息表transInfo
没有自动修改张三的余额
最优的解决方案就是采用触发器:
它是一种特殊的存储过程
也具备事务的功能
它能在多表之间执行特殊的业务规则
1.什么是触发器
赵二退休 删除
员工表
sqlserver用触发器记录增删改操作(转载)

sqlserver⽤触发器记录增删改操作(转载)数据库结构:CREATE TABLE[dbo].[cg_tz_log] ([logid]int NOT NULL IDENTITY(1,1) ,operate varchar(10), -- 操作类型如Insert,Update,Delete.id int, -- 原表ID(主键)[cg_date_o] date NULL ,[cg_date_n] date NULL ,[cg_id_o]varchar(255) NULL ,[cg_id_n]varchar(255) NULL ,[cg_sname_o]varchar(255) NULL ,[cg_sname_n]varchar(255) NULL ,[cg_cgpname_o]varchar(255) NULL ,[cg_cgpname_n]varchar(255) NULL ,[cg_ggxh_o]varchar(255) NULL ,[cg_ggxh_n]varchar(255) NULL ,[cg_pp_o]varchar(255) NULL ,[cg_pp_n]varchar(255) NULL ,[cg_num_o]int NULL ,[cg_num_n]int NULL ,[cg_dw_o]varchar(255) NULL ,[cg_dw_n]varchar(255) NULL ,[cg_price_o]money NULL ,[cg_price_n]money NULL ,[cg_priceall_o]money NULL ,[cg_priceall_n]money NULL ,[cg_htprice_o]money NULL ,[cg_htprice_n]money NULL ,[cg_htcbprice_o]money NULL ,[cg_htcbprice_n]money NULL ,[cg_xsht_o]varchar(255) NULL ,[cg_xsht_n]varchar(255) NULL ,[cg_xspname_o]varchar(255) NULL ,[cg_xspname_n]varchar(255) NULL ,[cg_lb_o]varchar(255) NULL ,[cg_lb_n]varchar(255) NULL ,[cg_f_date_o] date NULL ,[cg_f_date_n] date NULL ,[cg_f_percent_o]decimal(38,10) NULL ,[cg_f_percent_n]decimal(38,10) NULL ,[cg_f_price_o]money NULL ,[cg_f_price_n]money NULL ,[cg_nf_price_o]money NULL ,[cg_nf_price_n]money NULL ,[cg_p_id_o]varchar(255) NULL ,[cg_p_id_n]varchar(255) NULL ,[cg_p_price_o]money NULL ,[cg_p_price_n]money NULL ,[cg_dhqk_o]varchar(255) NULL ,[cg_dhqk_n]varchar(255) NULL ,[cg_sphone_o]varchar(255) NULL ,[cg_sphone_n]varchar(255) NULL ,[cg_sfax_o]varchar(255) NULL ,[cg_sfax_n]varchar(255) NULL ,[cg_slxr_o]varchar(255) NULL ,[cg_slxr_n]varchar(255) NULL ,[cg_dh_status_o]int NULL DEFAULT ((0)) ,[cg_dh_status_n]int NULL DEFAULT ((0)) ,[cg_dh_date_o] date NULL DEFAULT ('2017-9-27') ,[cg_dh_date_n] date NULL DEFAULT ('2017-9-27') ,[cg_dhzq_o]int NULL DEFAULT ((30)) ,[cg_dhzq_n]int NULL DEFAULT ((30)) ,[cg_kfid_o]varchar(255) NULL DEFAULT'',[cg_kfid_n]varchar(255) NULL DEFAULT'',spid int not null, -- spidlogin_name varchar(100), -- 登录名prog_name varchar(100), -- 程序名hostname varchar(100), -- 主机名ipaddress varchar(100), -- IP地址runsql varchar(4000), -- 执⾏的TSQL代码UDate datetime-- 操作⽇期时间)GO-- ----------------------------ALTER TABLE[dbo].[cg_tz_log]ADD PRIMARY KEY ([id])GO触发器:-- 建跟踪触发器create trigger tr_cg_tz_logon cg_tz after update,insert,deleteasbegindeclare@di table(et varchar(200),pt varchar(200),ei varchar(max))insert into@di exec('dbcc inputbuffer(@@spid)')declare@op varchar(10)select@op=case when exists(select1from inserted) and exists(select1from deleted)then'Update'when exists(select1from inserted) and not exists(select1from deleted)then'Insert'when not exists(select1from inserted) and exists(select1from deleted)then'Delete'endif@op in('Update','Insert')begininsert into cg_tz_log(operate,id,cg_date_o,cg_date_n,cg_id_o,cg_id_n,cg_sname_o,cg_sname_n,cg_cgpname_o,cg_cgpname_n,cg_ggxh_o,cg_ggxh_n,cg_pp_o,cg_pp_n,cg_num_o,cg_num_n,cg_dw_o,cg_dw_n,cg_price_o,cg_price_n,cg_priceall_o,cg_priceall_n,cg_htprice_o,cg_htprice_n,cg_htcbprice_o,cg_htcbprice_n,cg_xsht_o,cg_xsht_n,cg_xspname_o,cg_xspname_n,cg_lb_o,cg_lb_n,cg_f_date_o,cg_f_date_n,cg_f_percent_o,cg_f_percent_n,cg_f_price_o,cg_f_price_n,cg_nf_price_o,cg_nf_price_n,cg_p_id_o,cg_p_id_n, cg_p_price_o,cg_p_price_n,cg_dhqk_o,cg_dhqk_n,cg_sphone_o,cg_sphone_n,cg_sfax_o,cg_sfax_n,cg_slxr_o,cg_slxr_n,cg_dh_status_o,cg_dh_status_n,cg_dh_date_o,cg_dh_date_n,cg_dhzq_o,cg_dhzq_n,cg_kfid_o,cg_kfid_n,spid,login_name,prog_name,hostname,ipaddress,runsql,UDate)select@op,n.id,o.cg_date,n.cg_date,o.cg_id,n.cg_id,o.cg_sname,n.cg_sname,o.cg_cgpname,n.cg_cgpname,o.cg_ggxh,n.cg_ggxh,o.cg_pp,n.cg_pp,o.cg_num,n.cg_num,o.cg_dw,n.cg_dw,o.cg_price,n.cg_price,o.cg_priceall,n.cg_priceall,o.cg_htprice,n.cg_htprice,o.cg_htcbprice,n.cg_htcbprice,o.cg_xsht,n.cg_xsht,o.cg_xspname,n.cg_xspname,o.cg_lb,n.cg_lb,o.cg_f_date,n.cg_f_date,o.cg_f_percent,n.cg_f_percent,o.cg_f_price,n.cg_f_price,o.cg_nf_price,n.cg_nf_price,o.cg_p_id,n.cg_p_id,o.cg_p_price,n.cg_p_price,o.cg_dhqk,n.cg_dhqk,o.cg_sphone,n.cg_sphone,o.cg_sfax,n.cg_sfax,o.cg_slxr,n.cg_slxr,o.cg_dh_status,n.cg_dh_status,o.cg_dh_date,n.cg_dh_date,o.cg_dhzq,n.cg_dhzq,o.cg_kfid,n.cg_kfid,@@spid,(select login_name from sys.dm_exec_sessions where session_id=@@spid),(select program_name from sys.dm_exec_sessions where session_id=@@spid),(select hostname from sys.sysprocesses where spid=@@spid),(select client_net_address from sys.dm_exec_connections where session_id=@@spid),(select top1isnull(ei,'') from@di),getdate()from inserted nleft join deleted o on o.id=n.idendelsebegininsert into cg_tz_log(operate,id,cg_date_o,cg_date_n,cg_id_o,cg_id_n,cg_sname_o,cg_sname_n,cg_cgpname_o,cg_cgpname_n,cg_ggxh_o,cg_ggxh_n,cg_pp_o,cg_pp_n,cg_num_o,cg_num_n,cg_dw_o,cg_dw_n,cg_price_o,cg_price_n,cg_priceall_o,cg_priceall_n,cg_htprice_o,cg_htprice_n,cg_htcbprice_o,cg_htcbprice_n,cg_xsht_o,cg_xsht_n,cg_xspname_o,cg_xspname_n,cg_lb_o,cg_lb_n,cg_f_date_o,cg_f_date_n,cg_f_percent_o,cg_f_percent_n,cg_f_price_o,cg_f_price_n,cg_nf_price_o,cg_nf_price_n,cg_p_id_o,cg_p_id_n, cg_p_price_o,cg_p_price_n,cg_dhqk_o,cg_dhqk_n,cg_sphone_o,cg_sphone_n,cg_sfax_o,cg_sfax_n,cg_slxr_o,cg_slxr_n,cg_dh_status_o,cg_dh_status_n,cg_dh_date_o,cg_dh_date_n,cg_dhzq_o,cg_dhzq_n,cg_kfid_o,cg_kfid_n,spid,login_name,prog_name,hostname,ipaddress,runsql,UDate)select@op,o.id,o.cg_date,null,o.cg_id,null,o.cg_sname,null,o.cg_cgpname,null,o.cg_ggxh,null,o.cg_pp,null,o.cg_num,null,o.cg_dw,null,o.cg_price,null,o.cg_priceall,null,o.cg_htprice,null,o.cg_htcbprice,null,o.cg_xsht,null,o.cg_xspname,null,o.cg_lb,null,o.cg_f_date,null,o.cg_f_percent,null,o.cg_f_price,null,o.cg_nf_price,null,o.cg_p_id,null,o.cg_p_price,null,o.cg_dhqk,null,o.cg_sphone,null,o.cg_sfax,null,o.cg_slxr,null,o.cg_dh_status,null,o.cg_dh_date,null,o.cg_dhzq,null,o.cg_kfid,null,@@spid,(select login_name from sys.dm_exec_sessions where session_id=@@spid),(select program_name from sys.dm_exec_sessions where session_id=@@spid),(select hostname from sys.sysprocesses where spid=@@spid),(select client_net_address from sys.dm_exec_connections where session_id=@@spid),(select top1isnull(ei,'') from@di),getdate()from deleted oendendgo。
SQL Server存储过程和触发器操作实训讲义

SQL Server存储过程和触发器操作实训一、由已给数据库文件完成下列SQL存储过程操作1、创建和执行不带参数的存储过程创建一个存储过程p1,返回所有女生信息。
2、创建和执行带参数的存储过程(1)创建一个存储过程p2,返回指定系部的学生信息。
(输入参数)(2)创建从sc表查询指定学生学号的总成绩的存储过程p3。
(输入和输出参数)(3)创建一个名为Query_student的存储过程,该存储过程的功能是根据学号查询学生表中某一学生的姓名、系别、性别及年龄。
(输入参数)执行存储过程Query_student,查询学号为”9512103”的学生的姓名、系别、性别及年龄。
写出完成此功能的SQL命令。
3、创建和执行带输入参数的存储过程(1)创建一个能向学生表中插入一条记录的存储过程Insert_student,该过程需要5个参数,分别用来传递学号、姓名、性别、年龄、系别5个值。
写出执行存储过程Insert_student的SQL语句,向学生表中插入一个新同学,并提供相应的实参值(实参值自定)。
create procedure Insert_student( @no char(10),@name char(8),@sex char(2),@age int,@ dept char(10) )ASbegininsert into s(sno,sname,ssex,sage,sdept)values(@no,@name,@sex,@age,@dept)endEXEC Insert_student @no='9512104', @name='徐小花',@sex='女', @age=20, @dept='计算机系'(2)在课程表中添加“学分”列,类型为小整型,然后创建一个向课程表中插入一门新课程的存储过程Insert_course,该存储过程需要三个参数,分别用来传递课程号、课程名、学分,但允许参数“学分”的默认值为2,即当执行存储过程Insert_course时,未给参数“学分”提供实参值时,存储过程将按默认值2进行运算。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
SQLServer 触发器使用实例
触发器是一个特殊的存储过程。
常见的有三种:分别应用于Insert , Update , Delete 事件。
一、Trigger语法:
create trigger tr_name
on 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 ,inserted
deleted 和inserted 可以说是一种特殊的临时表,是在进行激活触发器时由系统自动生成的,其结构与触发器作用的表结构是一
样的,只是存放的数据有差异。
二、实例:
实例1(注意这里的关联,条件是如何关联,update中set的值是与谁关联。
这些都可以从【触发器的两个临时表:inserted、deleted】中得到答案)
比如,这么两个表:
Create Table Student( --学生表
StudentID int primary key, --学号
StudentName varchar(50),姓名
)
Create Table BorrowRecord( --学生借书记录表
BorrowRecord int identity(1,1), --流水号
StudentID int , --学号
BorrowDate datetime, --借出时间
ReturnDAte Datetime, --归还时间
...
)
用到的功能有:
1.如果我更改了学生的学号,我希望他的借书记录仍然与这个学生相关(也就是同时更改借书记录表的学号);
2.如果该学生已经毕业,我希望删除他的学号的同时,也删除它的借书记录。
等等。
这时候可以用到触发器。
对于1,创建一个Update触发器:
Create Trigger truStudent
On Student --在Student表中创建触发器
for Update --为什么事件触发
As --事件触发后所要做的事情
if Update(StudentID)
begin
Update BorrowRecord
Set StudentID=i.StudentID
From BorrowRecord br , Deleted d ,Inserted i --Deleted和Inserted临时表
Where br.StudentID=d.StudentID
end
理解触发器里面的两个临时的表:Deleted , Inserted 。
注意Deleted 与Inserted分别表示触发事件的表“旧的一条记录”和“新的一条记录”。
一个数据库系统中有两个虚拟表用于存储在表中记录改动的信息,分别是:
| 虚拟表Inserted | 虚拟表Deleted
在表记录新增时| 存放新增的记录| 不存储记录
修改时| 存放用来更新的新记录| 存放更新前的记录
删除时| 不存储记录 | 存放被删除的记录
一个Update 的过程可以看作为:生成新的记录到Inserted表,复制旧的记录到Deleted表,然后删除Student记录并写入新纪录。
对于2,创建一个Delete触发器
Create trigger trdStudent
On Student
for Delete
As
Delete BorrowRecord
From BorrowRecord br , Delted d
Where br.StudentID=d.StudentID
对于3,创建一个Insert触发器
create Trigger testdb
on myStudent
for insert
as
begin
insert into BorrowRecord(StudentID,Sex) select studentid,username from inserted myStudent
end
从这两个例子我们可以看到了触发器的关键:A.2个临时的表;B.触发机制。