SQL Server 触发器
2013-11-05 10:36
363 查看
ctreate database tttt; 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> goINSERT注: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 实现在触发以后,判断哪些列被更新了.
相关文章推荐
- SQL Server 触发器创建、删除、修改、查看示例
- sql server 2000/2005 判断存储过程、触发器、视图是否存在并删除
- SQL Server 触发器
- SQL Server创建触发器
- SQL Server的触发器用法
- SQL Server 触发器
- SQL Server 触发器
- SQL Server 触发器
- 避免SQL Server 触发器死循环
- SQL Server 触发器
- SQL Server 存储过程与触发器
- SQL Server 触发器(内容非常不错,转载记录)
- SQL server 触发器
- sql server 触发器简单学习
- SQL Server误区30日谈 第4天 DDL触发器就是INSTEAD OF触发器
- SQL Server 触发器
- Sql server 2005触发器发送http请求
- 查看SQL SERVER 加密存储过程,函数,触发器,视图
- SQL Server 触发器
- SQL SERVER的多行删除触发器use cursor