我有一个触发器,在插入记录时触发。应用程序修改员工的银行记录,但每次创建四条记录,无论是否只更新或插入一个字段
例如,您更新员工的帐号。应用程序将在审计表中插入四行,包括记录类型帐号,帐户类型,银行和分支。每个插入的行都有一个旧值和一个新值。
数据看起来像这样:
Auditfieldid, recordtype, old value, new value
----------------------------------------------
1, account number, 99, 88
1, account type, C, A
1, bank, BOA, Regions
1, branch, Cedar Bluff, Clinton
我希望触发器遍历插入的记录,但在临时表中构建一行包含:
Auditfieldid, AccountNoOldvalue, AccountNoNewValue, AccountTypeOldValue,
AccountTypeNewValue, BankOldValue, BankNewValue, BranchOldValue, BranchNewValue
---------------------------------------------------------------------------------
1, 99, 88, C, A, BOA, Regions, Cedar Bluff, Clinton
然后,上面的数据会在HTML电子邮件中显示。如果我不做上述操作,则会收到4封电子邮件作为通知发送,我只想要一封包含所有值的电子邮件。
这是我到目前为止所做的工作,但会生成4封电子邮件:
USE [SageStaging]
GO
/****** Object: Trigger [MASSMART].[Vip_BankChange_Email] Script Date: 2017-08-07 11:49:06 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
--USE [SageStaging]
--GO
/****** Object: Trigger [MASSMART].[Vip_BankChange_Email] Script Date: 2017-07-12 08:36:41 AM ******/
--SET ANSI_NULLS ON
--GO
--SET QUOTED_IDENTIFIER ON
--GO
--/------
ALTER TRIGGER [MASSMART].[Vip_BankChange_Email]
ON [MASSMART].[MM_BankAudit]
AFTER UPDATE
AS
SET NOCOUNT ON;
DECLARE @AUDITFIELDID NVARCHAR(500)
DECLARE @EFFECTIVEDATE VARCHAR(500)
DECLARE @VIPUSERNAME VARCHAR(500)
DECLARE @SOURCECODE VARCHAR(500)
DECLARE @ACTIONSDESCRIPTION VARCHAR(500)
DECLARE @FIELDNAME VARCHAR(500)
DECLARE @TABLEFRIENDLYNAME VARCHAR(500)
DECLARE @OLDVALUE NVARCHAR(500)
DECLARE @AUDITVALUE NVARCHAR(500)
DEClARE @COMPANYRULE NVARCHAR(MAX)
DECLARE @Mail_Profile_Name VARCHAR(100)
DECLARE @SENT VARCHAR(10)
SET @Mail_Profile_Name = 'Sendmail'
DECLARE @MessageBody VARCHAR(MAX)
DECLARE @MailSubject NVARCHAR(500)
DECLARE @@CC VARCHAR(50)
DECLARE @@Sendto NVARCHAR(100)
DECLARE @COMPANYRULEID NVARCHAR(100)
DECLARE @NUMKEY NVARCHAR(100)
DECLARE Email_cursor CURSOR FOR
SELECT AUDITFIELDID,
companyruleid,
effectivedate,
VIPUserName,
SourceCode,
ActionsDescription,
FieldName,
OldValue,
AuditValue,
CompanyRule,
Sent,
numkey
FROM inserted
OPEN Email_cursor;
FETCH NEXT FROM Email_cursor INTO @AUDITFIELDID, @companyruleid, @effectivedate, @VIPUserName, @SourceCode, @ActionsDescription, @FieldName, @OldValue, @AuditValue, @CompanyRule, @sent, @numkey
WHILE @@FETCH_STATUS = 0
BEGIN
SET @MailSubject = 'Banking Details Change Notification for Employee' + ' ' + @SOURCECODE
SET @MessageBody = '<html>
<head>
<meta content="text/html; charset=ISO-8859-1"
http-equiv="content-type">
<title></title>
</head>
<body>
<br>
The following bank details have been changed:
<br>
<br>
Date Changed: ' + @EFFECTIVEDATE + '<br>' +
' Username: ' + @VIPUSERNAME + '<br>' +
' Employee Details: ' + @SOURCECODE + '<br>' +
' Action: ' + @ACTIONSDESCRIPTION + '<br>' +
' Field: ' + @FIELDNAME + '<br>' +
' Old Value: ' + @OLDVALUE + '<br>' +
' New Value: ' + @AUDITVALUE + '<br>' +
' Company: ' + @COMPANYRULE + '<br>
<br>
<b>
Please do not respond to this email. If you have any questions regarding this email, please
contact your payroll administrator <br>
<br>
<br>
</body>
</html>'
-- Massmart Employers (Exec)
IF @COMPANYRULEID IN (36)
BEGIN
SET @@Sendto = 'john.doe@gmail.com'
END
-- Massmart Employers
IF @COMPANYRULEID IN (40,1,35,44)
BEGIN
SET @@Sendto = 'john.doe@gmail.com'
END
-- Cambridge Employers
IF @COMPANYRULEID IN (104,105,51,52,54,55,56,57)
BEGIN
SET @@Sendto = 'john.doe@gmail.com'
END
-- Builders Employers
IF @COMPANYRULEID IN (101,102,12,13,14,15,16,17,18,19,20,98)
BEGIN
SET @@Sendto = 'john.doe@gmail.com'
END
-- MDD Employers
IF @COMPANYRULEID IN (106,107,108,2,21,26,27,29,3,30,31,33,34,4,5,6,72,80,83,94,86,9,95,96,97,99)
BEGIN
SET @@Sendto = 'john.doe@gmail.com'
END
-- Unison
IF @COMPANYRULEID IN (37,39)
BEGIN
SET @@Sendto = 'Annie.mahadasen@massmart.co.za;Candice.mcanda@massmart.co.za;dknoetz@massmart.co.za'
END
-- FruitSpot
IF @COMPANYRULEID IN (46)
BEGIN
SET @@Sendto = 'john.doe@gmail.com'
END
-- Masscash
IF @COMPANYRULEID IN (103,58,60,63,64,65,66,68,69,79,81,85,89,90,91,92,93,94)
BEGIN
SET @@Sendto = 'john.doe@gmail.com'
END
-- Makro Employers
IF @COMPANYRULEID IN (70,47,48,50,78)
BEGIN
SET @@Sendto = 'john.doe@gmail.com'
END
EXEC msdb.dbo.sp_send_dbmail
@profile_name = @Mail_Profile_Name,
@recipients = @@Sendto,
@body = @MessageBody,
@subject = @MailSubject,
@body_format = 'HTML'
FETCH NEXT FROM Email_cursor INTO @AUDITFIELDID, @COMPANYRULEID, @effectivedate, @VIPUserName, @SourceCode, @ActionsDescription, @FieldName, @OldValue, @AuditValue, @CompanyRule, @sent
END
CLOSE Email_cursor
DEALLOCATE Email_cursor
答案 0 :(得分:0)
根据数据的插入方式,触发器只能在Inserted
中的四行中触发一次,或者每次在Inserted
中一行触发四次。
这是一个简单的例子,你可以像下面这样使用SELECT
来缩小一行中的所有值:
select ID,
(select OldValue from Inserted
where recordtype='account number' and ID=Temp.ID) as AccountNoOldvalue,
(select NewValue from Inserted
where recordtype='account number' and ID=Temp.ID) as AccountNoNewValue,
(select OldValue from Inserted
where recordtype='account type' and ID=Temp.ID) as AccountTypeOldValue,
(select NewValue from Inserted
where recordtype='account type' and ID=Temp.ID) as AccountTypeNewValue,
(select OldValue from Inserted
where recordtype='bank' and ID=Temp.ID) as BankOldValue,
(select NewValue from Inserted
where recordtype='bank' and ID=Temp.ID) as BankNewValue,
(select OldValue from Inserted
where recordtype='branch' and ID=Temp.ID) as BranchOldValue,
(select NewValue from Inserted
where recordtype='branch' and ID=Temp.ID) as BranchNewValue
from Inserted as Temp
group by ID
在这种情况下,如问题评论中所述,您无法在触发器内同时获取所有值。我会添加另一个审计表到数据库,从触发器填充它,当为给定的ID填充四种类型的更改,然后从新表的第二个触发器发送电子邮件:
create table AuditCondensed (
ID int,
AccountNoOldValue varchar(100),
AccountNoNewValue varchar(100),
AccountTypeOldValue varchar(100),
AccountTypeNewValue varchar(100),
BankOldValue varchar(100),
BankNewValue varchar(100),
BranchOldValue varchar(100),
BranchNewValue varchar(100)
)
go
create trigger trFillAuditCondensed on YourCurrentAuditTable
after insert as
declare @ID int, @RecordType char(25)
select @ID=ID, @RecordType=RecordType from Inserted
if not exists(select * from AuditCondensed where ID=@ID)
insert into AuditCondensed (ID) select ID from Inserted
if @RecordType='account number'
update AuditCondensed set AccountNoOldvalue=OldValue,
AccountNoNewValue=NewValue
from AuditCondensed
join Inserted on Inserted.ID=AuditCondensed.ID
if @RecordType='account type'
update AuditCondensed set AccountTypeOldValue=OldValue,
AccountTypeNewValue=NewValue
from AuditCondensed
join Inserted on Inserted.ID=AuditCondensed.ID
if @RecordType='bank'
update AuditCondensed set BankOldValue=OldValue,
BankNewValue=NewValue
from AuditCondensed
join Inserted on Inserted.ID=AuditCondensed.ID
if @RecordType='branch'
update AuditCondensed set BranchOldValue=OldValue,
BranchNewValue=NewValue
from AuditCondensed
join Inserted on Inserted.ID=AuditCondensed.ID
go
create trigger trSendEmail on AuditCondensed
after update as
if exists (select * from Inserted
where AccountNoNewValue is not null
and AccountTypeNewValue is not null
and BankNewValue is not null
and BranchNewValue is not null)
begin
-- sent your email here
end
go