SQL Server 触发器

ctreate database tttt;  CREATE TABLE    ;    CREATE TRIGGER  ; create cursor;  create  procedure;   
use tttt;
create table xxxx.............
 
 

SQL Server 触发器

测试表 1> CREATE TABLE test_trigger_table ( 2>     id     INT, 3>     name   VARCHAR(10), 4>     val    INT 5> ); 6> go

INSERT

注:SQL Server 中。 没有 BEFORE INSERT 或者 AFTER INSERT 根据文档显示,以及代码的测试。基本上类似于 Oracle 的 AFTER INSERT SQL Sercer 触发器 没有 FOR EACH ROW 关键字 一次更新一条,还是多条,取决于 INSERTED 里面的内容。 1> CREATE TRIGGER BeforeInsertTest 2>   ON test_trigger_table 3>   FOR INSERT 4> AS 5> DECLARE 6>   @Id   INT, 7>   @Name VARCHAR(10); 8> BEGIN 9>   PRINT('BEFORE INSERT'); 10>   SELECT @Id = id, @Name = name FROM INSERTED; 11>   PRINT('New Name = ' + @Name); 12>   UPDATE test_trigger_table SET val = 100 WHERE ; 13> END; 14> go 1> 2> INSERT INTO test_trigger_table(id, name) VALUES (1, 'ABC'); 3> go BEFORE INSERT New Name = ABC

(1 行受影响) 1> select * from test_trigger_table; 2> go id          name       val ----------- ---------- -----------           1 ABC                100

(1 行受影响)

UPDATE 1> CREATE TRIGGER AfterUpdateTest 2>   ON test_trigger_table 3>   FOR UPDATE 4> AS 5> DECLARE 6>   @OldName VARCHAR(10), 7>   @NewName VARCHAR(10); 8> BEGIN 9>   PRINT('AFTER UPDATE'); 10>   SELECT @NewName = name FROM inserted; 11>   SELECT @OldName = name FROM deleted; 12>   PRINT('Old Name = ' + @OldName); 13>   PRINT('New Name = ' + @NewName); 14> END; 15> go 1> 2> UPDATE test_trigger_table SET name = 'XYZ' WHERE id = 1; 3> go AFTER UPDATE Old Name = ABC

(1 行受影响) New Name = XYZ

DELETE 1> CREATE TRIGGER AfterDeleteTest 2>   ON test_trigger_table 3>   FOR DELETE 4> AS 5> DECLARE 6>   @OldName VARCHAR(10); 7> BEGIN 8>   PRINT('AFTER DELETE'); 9>   SELECT @OldName = name FROM deleted; 10>   PRINT('Old Name = ' + @OldName); 11> END; 12> go 1> DELETE FROM test_trigger_table WHERE id = 1; 2> go AFTER DELETE

(1 行受影响) Old Name = XYZ

INSERT/UPDATE/DELETE行为判断 测试此处时,先删除前面的3个触发器 1> CREATE TRIGGER AfterAllTest 2>   ON test_trigger_table 3>   FOR INSERT,UPDATE,DELETE 4> AS 5> BEGIN 6>   PRINT('AFTER ALL'); 7>   IF EXISTS(SELECT 1 FROM inserted) AND NOT EXISTS(SELECT 1 FROM deleted) 8>   BEGIN 9>     PRINT('INSERTING'); 10>   END; 11>   IF EXISTS(SELECT 1 FROM inserted) AND EXISTS(SELECT 1 FROM deleted) 12>   BEGIN 13>     PRINT('UPDATING'); 14>   END; 15>   IF NOT EXISTS(SELECT 1 FROM inserted) AND EXISTS(SELECT 1 FROM deleted) 16>   BEGIN 17>     PRINT('DELETING'); 18>   END; 19> END; 20> go 1> INSERT INTO test_trigger_table(id, name) VALUES (1, 'ABC'); 2> UPDATE test_trigger_table SET name = 'XYZ' WHERE id = 1; 3> DELETE FROM test_trigger_table WHERE id = 1; 4> go AFTER ALL INSERTING

(1 行受影响) AFTER ALL UPDATING AFTER ALL DELETING 1>

SQL Server INSERT/UPDATE/DELETE多行 1> CREATE TRIGGER AfterAllTest2 2>    ON test_trigger_table 3>    FOR INSERT,UPDATE,DELETE 4> AS 5> DECLARE 6>   @InsertCount INT, 7>   @DeleteCount INT; 8> BEGIN 9>   PRINT('AFTER ALL 2'); 10>   SELECT @InsertCount = COUNT(1) FROM inserted; 11>   SELECT @DeleteCount = COUNT(2) FROM deleted; 12>   PRINT('@InsertCount=' + STR(@InsertCount) ); 13>   PRINT('@DeleteCount=' + STR(@DeleteCount) ); 14> END; 15> go 1> INSERT INTO test_trigger_table(id, name) VALUES (1, 'ABC'); 2> go AFTER ALL INSERTING AFTER ALL 2 @InsertCount=         1

(1 行受影响) @DeleteCount=         0 1> INSERT INTO test_trigger_table(id, name) VALUES (2, 'DEF'); 2> go AFTER ALL INSERTING AFTER ALL 2 @InsertCount=         1

(1 行受影响) @DeleteCount=         0 1> insert into test_trigger_table select * from test_trigger_table; 2> go AFTER ALL INSERTING AFTER ALL 2 @InsertCount=         2

(2 行受影响) @DeleteCount=         0 1> UPDATE test_trigger_table SET name = 'XYZ' WHERE id = 1; 2> go AFTER ALL UPDATING AFTER ALL 2 @InsertCount=         2

(2 行受影响) @DeleteCount=         2 1>

针对特定列的触发 测试此处时,先删除其它的触发器

SQL Server 通过  COLUMNS_UPDATED 来判断哪些列被更新 COLUMNS_UPDATED 函数以从左到右的顺序返回位,最左边的为最不重要的位。 最左边的位表示表中的第一列;向右的下一位表示第二列,依此类推。 如果在表上创建的触发器包含 8 列以上,则 COLUMNS_UPDATED 返回多个字节,最左边的为最不重要的字节。 在 INSERT 操作中 COLUMNS_UPDATED 将对所有列返回 TRUE 值,因为这些列插入了显式值或隐性 (NULL) 值。

1> drop TRIGGER AfterUpdateTest; 2> go 1> CREATE TRIGGER AfterUpdateTest 2>   ON test_trigger_table 3>   FOR INSERT, UPDATE 4> AS 5> DECLARE 6>   @OldVal VARCHAR(10), 7>   @NewVal VARCHAR(10); 8> BEGIN 9> 10>   IF (COLUMNS_UPDATED() & 4 ) > 0 11>   BEGIN 12>     PRINT('AFTER UPDATE Only Val'); 13>     SELECT @NewVal = val FROM inserted; 14>     SELECT @OldVal = val FROM deleted; 15>     PRINT('Old Val = ' + @OldVal); 16>     PRINT('New Val = ' + @NewVal); 17>   END; 18> END 19> go 1> INSERT INTO test_trigger_table(id, name, val) VALUES (1, 'ABC', 1); 2> go AFTER UPDATE Only Val

(1 行受影响) New Val = 1 1> 2> UPDATE test_trigger_table SET name = 'XYZ' WHERE id=1; 3> go

(1 行受影响) 1> 2> UPDATE test_trigger_table SET val = 20 WHERE id=1; 3> go AFTER UPDATE Only Val Old Val = 1

(1 行受影响) New Val = 20

已创建的触发器的查询 1> select 2>   name 3> from 4>   sysobjects 5> where 6>   xtype='TR' 7>   and parent_obj=object_id('table_1') 8> go name

-------------------------------------------------------------------------------- ------------------------------------------------ AfterInsertTable_1

(1 行受影响)

DDL触发器 数据库级别 1> CREATE TRIGGER CretaeTableTrigger 2> ON DATABASE 3> FOR CREATE_TABLE 4> AS 5> BEGIN 6>   DECLARE @EventData AS xml; 7> 8>   DECLARE @EventType     AS varchar(100); 9>   DECLARE @PostTime      AS varchar(100); 10>   DECLARE @ServerName    AS varchar(100); 11>   DECLARE @LoginName     AS varchar(100); 12>   DECLARE @DatabaseName AS varchar(100); 13>   DECLARE @CommandText   AS varchar(100); 14> 15>   SET @EventData = EVENTDATA(); 16> 17>   SELECT 18>     @EventType    = t.c.value('(EventType)[1]',      'varchar(100)' ), 19>     @PostTime     = t.c.value('(PostTime)[1]',       'varchar(100)' ), 20>     @ServerName   = t.c.value('(ServerName)[1]',     'varchar(100)' ), 21>     @LoginName    = t.c.value('(LoginName)[1]',      'varchar(100)' ), 22>     @DatabaseName = t.c.value('(DatabaseName)[1]',   'varchar(100)' ), 23>     @CommandText = t.c.value('(TSQLCommand/CommandText)[1]',   'varchar(100 )' ) 24>   FROM 25>     @EventData.nodes('/EVENT_INSTANCE') t(c); 26> 27>   PRINT( 'CREATE_TABLE' ); 28>   PRINT( @EventType ); 29>   PRINT( @PostTime ); 30>   PRINT( @ServerName ); 31>   PRINT( @LoginName ); 32>   PRINT( @DatabaseName ); 33>   PRINT( @CommandText ); 34> END 35> go 1> create table yyy (a INT); 2> go CREATE_TABLE CREATE_TABLE 2010-10-01T21:32:24.843 HOME-BED592453C\SQLEXPRESS HOME-BED592453C\wzq Stock create table yyy (a INT);

 

 

DDL触发器 服务器级别 1> CREATE TRIGGER ddl_trig_database 2> ON ALL SERVER 3> FOR CREATE_DATABASE 4> AS 5> BEGIN 6>   DECLARE @EventData     AS xml; 7>   DECLARE @DatabaseName AS varchar(100); 8>   DECLARE @Sql    NVARCHAR(200); 9> 10>   SET @EventData = EVENTDATA(); 11> 12>   SELECT 13>     @DatabaseName = t.c.value('(DatabaseName)[1]',   'varchar(100)' ) 14>   FROM 15>     @EventData.nodes('/EVENT_INSTANCE') t(c); 16> 17>   PRINT 'Database Created.' 18> 19>   SET @Sql = 20>     'CREATE TABLE ' + @DatabaseName + '.dbo.abc( a INT )' ; 21>   PRINT @Sql; 22>   EXEC (@Sql); 23> 24> END 25> GO 1> create database test2 2> go Database Created. CREATE TABLE test2.dbo.abc( a INT ) 1> use test2 2> go 已将数据库上下文更改为 'test2'。 1> select * from abc 2> go a -----------

(0 行受影响)

 

小结 触发器只有 语句级别的 只有 AFTER 取得 操作数据,通过 inserted deleted

编写触发器的时候,要充分考虑 一次更新一条,与一次更新多条的问题。 避免简单的 SELECT @NewName = name FROM inserted; 代码操作。

对于 FOR INSERT,UPDATE,DELETE 的 通过 查询 inserted 与 deleted 的记录 来判断

通过COLUMNS_UPDATED 实现在触发以后,判断哪些列被更新了

.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值