如何在 sql 服务器中使用条件触发器进行更新
how to use conditional trigger in sql server for update
我有一个 table 这样的:
---------------table1--------------------------------------------
id | name | lname | displayStatus | delStatus
1 a b 1 0
2 aa bb 0 0
3 aaa bbb 1 0
4 aaaa bbbb 0 1
---------------tbl_LOG--------------------------------------------
id | rowData| actType
我有这个更新触发器:
alter trigger tgr_delete
on table1
after update
as
begin
declare @rowData nvarchar(max), @username nvarchar(50)
if update(delStatus)
begin
if((select delStatus from inserted) = 1)
begin
set @rowData = (select CAST((CAST(id as nvarchar(12)) + ' | ' + name) as nvarchar(max)) from inserted)
exec sp_insert_LOG 'table1', @rowData, 2
end
else if((select delStatus from inserted) = 0)
begin
set @rowData = (select CAST((CAST(id as nvarchar(12)) + ' | ' + name) as nvarchar(max)) from inserted)
exec sp_insert_LOG 'table1', @rowData, 3
end
end
else if update(displayStatus)
begin
if((delStatus = 0 or delStatus is null) and (select displayStatus from inserted) = 0)
begin
set @rowData = (select CAST((CAST(id as nvarchar(12)) + ' | ' + name) as nvarchar(max)) from inserted)
exec sp_insert_LOG 'table1', @rowData, 4
end
else if((delStatus = 0 or delStatus is null) and (select displayStatus from inserted) = 1)
begin
set @rowData = (select CAST((CAST(id as nvarchar(12)) + ' | ' + name) as nvarchar(max)) from inserted)
exec sp_insert_LOG 'table1', @rowData, 5
end
end
end
我有 3 个存储过程
- 首先是更新 delStatus
- 第二个用于更新 displayStatus
- 第三个用于更新所有列
现在我应该怎么做才能避免干扰前两个条件。
这不是一个完整的答案,因为我不知道 sp_insert_LOG
是做什么的,但它应该能让你在正确的方向上开始:
CREATE TRIGGER trg_Table1_Update ON Table1
FOR UPDATE
AS
DECLARE @LogData AS TABLE
(
TableName sysname,
RowData nvarchar(max),
ActionType int
)
INSERT INTO @LogData (TableName, RowData, ActionType)
SELECT 'Table1',
CAST((CAST(id as nvarchar(12)) + ' | ' + name) as nvarchar(max)),
CASE WHEN i.delStatus = 1 THEN 2
WHEN i.delStatus = 0 THEN 3
WHEN ISNULL(i.delStatus, 0) = 0 AND i.displayStatus = 0 THEN 4
WHEN ISNULL(i.delStatus, 0) = 0 AND i.displayStatus = 1 THEN 5
END
FROM INSERTED i
INNER JOIN Deleted d ON i.Id = d.Id
WHERE (i.name = d.name OR i.name IS NULL and d.name IS NULL)
AND (i.lname = d.lname OR i.lname IS NULL and d.lname IS NULL)
AND
(
(
ISNULL(i.delStatus, 0) <> ISNULL(d.delStatus, 0)
AND ISNULL(i.displayStatus, 0) = ISNULL(d.displayStatus, 0)
)
OR
(
ISNULL(i.delStatus, 0) = ISNULL(d.delStatus, 0)
AND ISNULL(i.displayStatus, 0) <> ISNULL(d.displayStatus, 0)
)
)
此时,@LogData
table 包含您要发送到 sp_insert_LOG
的任何数据。我建议创建一个新的存储过程,如 sp_insert_log
,它将接受一个 table 值参数并处理该数据。
我有一个 table 这样的:
---------------table1--------------------------------------------
id | name | lname | displayStatus | delStatus
1 a b 1 0
2 aa bb 0 0
3 aaa bbb 1 0
4 aaaa bbbb 0 1
---------------tbl_LOG--------------------------------------------
id | rowData| actType
我有这个更新触发器:
alter trigger tgr_delete
on table1
after update
as
begin
declare @rowData nvarchar(max), @username nvarchar(50)
if update(delStatus)
begin
if((select delStatus from inserted) = 1)
begin
set @rowData = (select CAST((CAST(id as nvarchar(12)) + ' | ' + name) as nvarchar(max)) from inserted)
exec sp_insert_LOG 'table1', @rowData, 2
end
else if((select delStatus from inserted) = 0)
begin
set @rowData = (select CAST((CAST(id as nvarchar(12)) + ' | ' + name) as nvarchar(max)) from inserted)
exec sp_insert_LOG 'table1', @rowData, 3
end
end
else if update(displayStatus)
begin
if((delStatus = 0 or delStatus is null) and (select displayStatus from inserted) = 0)
begin
set @rowData = (select CAST((CAST(id as nvarchar(12)) + ' | ' + name) as nvarchar(max)) from inserted)
exec sp_insert_LOG 'table1', @rowData, 4
end
else if((delStatus = 0 or delStatus is null) and (select displayStatus from inserted) = 1)
begin
set @rowData = (select CAST((CAST(id as nvarchar(12)) + ' | ' + name) as nvarchar(max)) from inserted)
exec sp_insert_LOG 'table1', @rowData, 5
end
end
end
我有 3 个存储过程
- 首先是更新 delStatus
- 第二个用于更新 displayStatus
- 第三个用于更新所有列
现在我应该怎么做才能避免干扰前两个条件。
这不是一个完整的答案,因为我不知道 sp_insert_LOG
是做什么的,但它应该能让你在正确的方向上开始:
CREATE TRIGGER trg_Table1_Update ON Table1
FOR UPDATE
AS
DECLARE @LogData AS TABLE
(
TableName sysname,
RowData nvarchar(max),
ActionType int
)
INSERT INTO @LogData (TableName, RowData, ActionType)
SELECT 'Table1',
CAST((CAST(id as nvarchar(12)) + ' | ' + name) as nvarchar(max)),
CASE WHEN i.delStatus = 1 THEN 2
WHEN i.delStatus = 0 THEN 3
WHEN ISNULL(i.delStatus, 0) = 0 AND i.displayStatus = 0 THEN 4
WHEN ISNULL(i.delStatus, 0) = 0 AND i.displayStatus = 1 THEN 5
END
FROM INSERTED i
INNER JOIN Deleted d ON i.Id = d.Id
WHERE (i.name = d.name OR i.name IS NULL and d.name IS NULL)
AND (i.lname = d.lname OR i.lname IS NULL and d.lname IS NULL)
AND
(
(
ISNULL(i.delStatus, 0) <> ISNULL(d.delStatus, 0)
AND ISNULL(i.displayStatus, 0) = ISNULL(d.displayStatus, 0)
)
OR
(
ISNULL(i.delStatus, 0) = ISNULL(d.delStatus, 0)
AND ISNULL(i.displayStatus, 0) <> ISNULL(d.displayStatus, 0)
)
)
此时,@LogData
table 包含您要发送到 sp_insert_LOG
的任何数据。我建议创建一个新的存储过程,如 sp_insert_log
,它将接受一个 table 值参数并处理该数据。