sql触发器.docx

上传人:b****1 文档编号:2642927 上传时间:2023-05-04 格式:DOCX 页数:14 大小:20.06KB
下载 相关 举报
sql触发器.docx_第1页
第1页 / 共14页
sql触发器.docx_第2页
第2页 / 共14页
sql触发器.docx_第3页
第3页 / 共14页
sql触发器.docx_第4页
第4页 / 共14页
sql触发器.docx_第5页
第5页 / 共14页
sql触发器.docx_第6页
第6页 / 共14页
sql触发器.docx_第7页
第7页 / 共14页
sql触发器.docx_第8页
第8页 / 共14页
sql触发器.docx_第9页
第9页 / 共14页
sql触发器.docx_第10页
第10页 / 共14页
sql触发器.docx_第11页
第11页 / 共14页
sql触发器.docx_第12页
第12页 / 共14页
sql触发器.docx_第13页
第13页 / 共14页
sql触发器.docx_第14页
第14页 / 共14页
亲,该文档总共14页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

sql触发器.docx

《sql触发器.docx》由会员分享,可在线阅读,更多相关《sql触发器.docx(14页珍藏版)》请在冰点文库上搜索。

sql触发器.docx

sql触发器

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

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

二﹕SQLServer为每个触发器都创建了两个专用表﹕Inserted表和Deleted表。

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

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

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

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

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

三﹕Insteadof和After触发器

SQLServer2000提供了两种触发器﹕Insteadof和After触发器。

这两种触发器的差别在于他们被激活的同﹕

Insteadof触发器用于替代引起触发器执行的T-SQL语句。

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

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

After触发器只能用于表。

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

四﹕触发器的执行过程

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

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

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

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

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

五﹕使用T-SQL语句来创建触发器

基本语句如下﹕

createtriggertrigger_name

on{table_name|view_name}

{for|After|Insteadof}

[insert,update,delete]

as

sql_statement

六﹕删除触发器:

基本语句如下﹕

droptriggertrigger_name

七:

查看数据库中已有触发器:

--查看数据库已有触发器

usejxcSoftware

go

select*fromsysobjectswherextype='TR'

--查看单个触发器

execsp_helptext'触发器名'

八﹕修改触发器:

基本语句如下﹕

altertriggertrigger_name

on{table_name|view_name}

{for|After|Insteadof}

[insert,update,delete]

as

sql_statement

九﹕相关示例﹕

1﹕在Orders表中建立触发器﹐当向Orders表中插入一条订单记录时﹐检查goods表的货品状态status是否为1(正在整理)﹐是﹐则不能往Orders表加入该订单。

createtriggerorderinsert

onorders

afterinsert

as

if(selectstatusfromgoods,inserted

wheregoods.name=inserted.goodsname)=1

begin

print'thegoodsisbeingprocessed'

print'theordercannotbecommitted'

rollbacktransaction--回滚﹐避免加入

end

2﹕在Orders表建立一个插入触发器﹐在添加一条订单时﹐减少Goods表相应的货品记录中的库存。

createtriggerorderinsert1

onorders

afterinsert

as

updategoodssetstorage=storage-inserted.quantity

fromgoods,inserted

where

goods.name=inserted.goodsname

3﹕在Goods表建立删除触发器﹐实现Goods表和Orders表的级联删除。

createtriggergoodsdelete

ongoods

afterdelete

as

deletefromorders

wheregoodsnamein

(selectnamefromdeleted)

4﹕在Orders表建立一个更新触发器﹐监视Orders表的订单日期(OrderDate)列﹐使其不能手工修改.

createtriggerorderdateupdate

onorders

afterupdate

as

ifupdate(orderdate)

begin

raiserror('orderdatecannotbemodified',10,1)

rollbacktransaction

end

5﹕在Orders表建立一个插入触发器﹐保证向Orders表插入的货品名必须要在Goods表中一定存在。

createtriggerorderinsert3

onorders

afterinsert

as

if(selectcount(*)fromgoods,insertedwheregoods.name=inserted.goodsname)=0

begin

print'noentryingoodsforthisorder'

rollbacktransaction

end

6:

Orders表建立一个插入触发器,保证向Orders表插入的货品信息要在Order表中添加

altertriggeraddOrder

onOrders

forinsert

as

insertintoOrder

selectinserted.Id,inserted.goodName,inserted.Numberfrominserted

____________________________________________________________________

SQLServer触发器

触发器是一种特殊类型的存储过程,它不同于之前的我们介绍的存储过程。

触发器主要是通过事件进行触发被自动调用执行的。

而存储过程可以通过存储过程的名称被调用。

Ø什么是触发器

   触发器对表进行插入、更新、删除的时候会自动执行的特殊存储过程。

触发器一般用在check约束更加复杂的约束上面。

触发器和普通的存储过程的区别是:

触发器是当对某一个表进行操作。

诸如:

update、insert、delete这些操作的时候,系统会自动调用执行该表上对应的触发器。

SQLServer2005中触发器可以分为两类:

DML触发器和DDL触发器,其中DDL触发器它们会影响多种数据定义语言语句而激发,这些语句有create、alter、drop语句。

 

   DML触发器分为:

   1、after触发器(之后触发)

       a、insert触发器

       b、update触发器

       c、delete触发器

 

   2、insteadof触发器(之前触发)

 

   其中after触发器要求只有执行某一操作insert、update、delete之后触发器才被触发,且只能定义在表上。

而insteadof触发器表示并不执行其定义的操作(insert、update、delete)而仅是执行触发器本身。

既可以在表上定义insteadof触发器,也可以在视图上定义。

 

   触发器有两个特殊的表:

插入表(instered表)和删除表(deleted表)。

这两张是逻辑表也是虚表。

有系统在内存中创建者两张表,不会存储在数据库中。

而且两张表的都是只读的,只能读取数据而不能修改数据。

这两张表的结果总是与被改触发器应用的表的结构相同。

当触发器完成工作后,这两张表就会被删除。

Inserted表的数据是插入或是修改后的数据,而deleted表的数据是更新前的或是删除的数据。

 

对表的操作

Inserted逻辑表

Deleted逻辑表

增加记录(insert)

存放增加的记录

删除记录(delete)

存放被删除的记录

修改记录(update)

存放更新后的记录

存放更新前的记录

   Update数据的时候就是先删除表记录,然后增加一条记录。

这样在inserted和deleted表就都有update后的数据记录了。

注意的是:

触发器本身就是一个事务,所以在触发器里面可以对修改数据进行一些特殊的检查。

如果不满足可以利用事务回滚,撤销操作。

 

Ø创建触发器

   语法

createtriggertgr_name

ontable_name

withencrypion–加密触发器

forupdate...

as

Transact-SQL

   #创建insert类型触发器

--创建insert插入类型触发器

if(object_id('tgr_classes_insert','tr')isnotnull)

droptriggertgr_classes_insert

go

createtriggertgr_classes_insert

onclasses

forinsert--插入触发

as

--定义变量

declare@idint,@namevarchar(20),@tempint;

--在inserted表中查询已经插入记录信息

select@id=id,@name=namefrominserted;

set@name=@name+convert(varchar,@id);

set@temp=@id/2;

insertintostudentvalues(@name,18+@id,@temp,@id);

print'添加学生成功!

';

go

--插入数据

insertintoclassesvalues('5班',getDate());

--查询数据

select*fromclasses;

select*fromstudentorderbyid;

    insert触发器,会在inserted表中添加一条刚插入的记录。

 

   #创建delete类型触发器

--delete删除类型触发器

if(object_id('tgr_classes_delete','TR')isnotnull)

droptriggertgr_classes_delete

go

createtriggertgr_classes_delete

onclasses

fordelete--删除触发

as

print'备份数据中……';

if(object_id('classesBackup','U')isnotnull)

--存在classesBackup,直接插入数据

insertintoclassesBackupselectname,createDatefromdeleted;

else

--不存在classesBackup创建再插入

select*intoclassesBackupfromdeleted;

print'备份数据成功!

';

go

--

--不显示影响行数

--setnocounton;

deleteclasseswherename='5班';

--查询数据

select*fromclasses;

select*fromclassesBackup;

  delete触发器会在删除数据的时候,将刚才删除的数据保存在deleted表中。

 

   #创建update类型触发器

--update更新类型触发器

if(object_id('tgr_classes_update','TR')isnotnull)

droptriggertgr_classes_update

go

createtriggertgr_classes_update

onclasses

forupdate

as

declare@oldNamevarchar(20),@newNamevarchar(20);

--更新前的数据

select@oldName=namefromdeleted;

if(exists(select*fromstudentwherenamelike'%'+@oldName+'%'))

begin

--更新后的数据

select@newName=namefrominserted;

updatestudentsetname=replace(name,@oldName,@newName)wherenamelike'%'+@oldName+'%';

print'级联修改数据成功!

';

end

else

print'无需修改student表!

';

go

--查询数据

select*fromstudentorderbyid;

select*fromclasses;

updateclassessetname='五班'wherename='5班';

    update触发器会在更新数据后,将更新前的数据保存在deleted表中,更新后的数据保存在inserted表中。

 

   #update更新列级触发器

if(object_id('tgr_classes_update_column','TR')isnotnull)

droptriggertgr_classes_update_column

go

createtriggertgr_classes_update_column

onclasses

forupdate

as

--列级触发器:

是否更新了班级创建时间

if(update(createDate))

begin

raisError('系统提示:

班级创建时间不能修改!

',16,11);

rollbacktran;

end

go

--测试

select*fromstudentorderbyid;

select*fromclasses;

updateclassessetcreateDate=getDate()whereid=3;

updateclassessetname='四班'whereid=7;

    更新列级触发器可以用update是否判断更新列记录;

 

   #insteadof类型触发器

      insteadof触发器表示并不执行其定义的操作(insert、update、delete)而仅是执行触发器本身的内容。

      创建语法

createtriggertgr_name

ontable_name

withencryption

insteadofupdate...

as

T-SQL

   

     #创建insteadof触发器

if(object_id('tgr_classes_inteadOf','TR')isnotnull)

droptriggertgr_classes_inteadOf

go

createtriggertgr_classes_inteadOf

onclasses

insteadofdelete/*,update,insert*/

as

declare@idint,@namevarchar(20);

--查询被删除的信息,病赋值

select@id=id,@name=namefromdeleted;

print'id:

'+convert(varchar,@id)+',name:

'+@name;

--先删除student的信息

deletestudentwherecid=@id;

--再删除classes的信息

deleteclasseswhereid=@id;

print'删除[id:

'+convert(varchar,@id)+',name:

'+@name+']的信息成功!

';

go

--test

select*fromstudentorderbyid;

select*fromclasses;

deleteclasseswhereid=7;

   

     #显示自定义消息raiserror

if(object_id('tgr_message','TR')isnotnull)

droptriggertgr_message

go

createtriggertgr_message

onstudent

afterinsert,update

asraisError('tgr_message触发器被触发',16,10);

go

--test

insertintostudentvalues('lily',22,1,7);

updatestudentsetsex=0wherename='lucy';

select*fromstudentorderbyid;

   #修改触发器

altertriggertgr_message

onstudent

afterdelete

asraisError('tgr_message触发器被触发',16,10);

go

--test

deletefromstudentwherename='lucy';

   #启用、禁用触发器

--禁用触发器

disabletriggertgr_messageonstudent;

--启用触发器

enabletriggertgr_messageonstudent;

   #查询创建的触发器信息

--查询已存在的触发器

select*fromsys.triggers;

select*fromsys.objectswheretype='TR';

--查看触发器触发事件

selectte.*fromsys.trigger_eventstejoinsys.triggerst

ont.object_id=te.object_id

wheret.parent_class=0andt.name='tgr_valid_data';

--查看创建触发器语句

execsp_helptext'tgr_message';

   #示例,验证插入数据

if((object_id('tgr_valid_data','TR')isnotnull))

droptriggertgr_valid_data

go

createtriggertgr_valid_data

onstudent

afterinsert

as

declare@ageint,

@namevarchar(20);

select@name=s.name,@age=s.agefrominserteds;

if(@age<18)

begin

raisError('插入新数据的age有问题',16,1);

rollbacktran;

end

go

--test

insertintostudentvalues('forest',2,0,7);

insertintostudentvalues('forest',22,0,7);

select*fromstudentorderbyid;

   #示例,操作日志

if(object_id('log','U')isnotnull)

droptablelog

go

createtablelog(

idintidentity(1,1)primarykey,

actionvarchar(20),

createDatedatetimedefaultgetDate()

go

if(exists(select*fromsys.objectswherename='tgr_student_log'))

droptriggertgr_student_log

go

createtriggertgr_student_log

onstudent

afterinsert,update,delete

as

if((exists(select1frominserted))and(exists(select1fromdeleted)))

begin

insertintolog(action)values('updated');

end

elseif(exists(select1frominserted)andnotexists(select1fromdeleted))

begin

insertintolog(action)values('inserted');

end

elseif(notexists(select1frominserted)andexists(select1fromdeleted))

begin

insertintolog(action)values('deleted');

end

go

--test

insertintostudentvalues('king',22,1,7);

updatestudentsetsex=0wherename='king';

deletestudentwherename='king';

select*fromlog;

select*fromstudentorderby

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 高等教育 > 医学

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2