For 和 After 触发器是在 SQLSERVER 服务器接到执行 SQL 语句请求之后,先建立 Inserted 和 Updated 临时表,然后在更改物理表上的数据,最后才激活触发器程序。
Instead Of 触发器在 SQLSERVER 服务器接到执行 SQL 语句请求,建立 Inserted 和 Updated 临时表后就激活了 Instead Of 触发器程序,至于 SQL 语句的请求如何操作数据就不在管了,把执行权全权叫给了 Instead Of 触发器。
For 和 After 触发器工作流程图
示例
用户表(User)
id
用户编号,主键
user_name
用户名
phone
电话
书籍信息(BookInfo)
id
书籍编号,主键
book_name
书籍名
price
单价
订单(Order)
id
订单编号,主键
user_id
用户ID
book_id
书籍ID
number
数量
price
总价
-- 创建表
IF EXISTS(SELECT Name FROM Sysobjects WHERE Name = 'User')
DROP TABLE [User]
GO
CREATE TABLE [User](
[id] int IDENTITY(100,1) PRIMARY KEY ,
[user_name] nvarchar(10) not null,
[phone] nvarchar(20)
)
IF EXISTS(SELECT Name FROM Sysobjects WHERE Name = 'BookInfo')
DROP TABLE [BookInfo]
GO
CREATE TABLE [BookInfo](
[id] int IDENTITY(100,1) PRIMARY KEY ,
[book_name] nvarchar(100) not null,
[price] decimal(20,2) not null
)
IF EXISTS(SELECT Name FROM Sysobjects WHERE Name = 'Order')
DROP TABLE [Order]
GO
CREATE TABLE [Order](
[id] int IDENTITY(100,1) PRIMARY KEY ,
[user_id] int not null,
[book_id] int not null,
[number] int not null,
[price] decimal(20,2)
)
-- 添加初始化语句
SET IDENTITY_INSERT [User] ON
INSERT INTO [User]([id],[user_name],[phone]) VALUES(100,'周卓浩','15782825513'),(101,'张悌斯','18269893952'),(102,'孙来笙','15907734953'),(103,'岳列洋','18042932995')
SET IDENTITY_INSERT [User] OFF
SET IDENTITY_INSERT [BookInfo] ON
INSERT INTO [BookInfo]([id],[book_name],[price]) VALUES(100,'Python编程 从入门到实践','65.00'),(101,'征服:如何赢得客户','52.20'),(102,'图解急救知识百科','75.80'),(103,'货币战争4 :战国时代','45.50')
SET IDENTITY_INSERT [BookInfo] OFF
-- 查询订单信息
SELECT
[Order].[id] '订单ID',
[User].[user_name] '用户名',
[BookInfo].[book_name] '书籍名称',
[BookInfo].[price] '单价',
[Order].[number] '数量',
[Order].[price] '总价'
FROM
[Order]
LEFT JOIN [User] ON [Order].[user_id] = [User].[id]
LEFT JOIN [BookInfo] ON [Order].[book_id] = [BookInfo].[id]
在 Order 表创建触发器update_order_price_trigger,用于计算正确总价
尽量不要使用游标,游标性能差
例 1:使用游标
CREATE TRIGGER update_order_price_trigger ON [Order]
FOR INSERT,UPDATE
AS
BEGIN
DECLARE @id1 INT
-- 定义游标
DECLARE cursor1 CURSOR FOR
SELECT [id] FROM [inserted]
-- 打开游标
OPEN cursor1
-- 获取第一行数据
FETCH NEXT FROM cursor1 INTO @id1
-- 通过判断@@FETCH_STATUS进行循环
WHILE @@FETCH_STATUS = 0
BEGIN
UPDATE [Order]
SET [Order].[price] = [Order].[number] * [BookInfo].[Price]
FROM [Order]
LEFT JOIN [BookInfo] ON [Order].[book_id] = [BookInfo].[id]
WHERE [Order].[id] =@id1
-- 获取下一行数据
FETCH NEXT FROM cursor1 INTO @id1
END
CLOSE cursor1
DEALLOCATE cursor1
END
例 2:不使用游标
CREATE TRIGGER update_order_price_trigger ON [Order]
FOR INSERT,UPDATE
AS
BEGIN
UPDATE [Order] SET [Order].[price] = [Order].[number] * [BookInfo].[Price]
FROM [inserted]
LEFT JOIN [Order] ON [inserted].[id] = [Order].[id]
LEFT JOIN [BookInfo] ON [Order].[book_id] = [BookInfo].[id]
END