插入/更新/删除/“后,我有一个触发器”。它应该根据Transaction表中的事务计算账户余额表。它在Transaction表上。我很少得到平衡差异,所以决定添加一些日志记录。它将插入的+已删除的表(它们组合成表var)和 tsql 语句转储它。从我的日志判断,看起来触发器没有触发某些插入到Transaction表中。这会发生吗?是否有任何TSQL语句更改表数据而不触发触发器(截断表等除外)?
以下是触发器:
CREATE TRIGGER [dbo].[trg_AccountBalance]
ON [dbo].[tbl_GLTransaction]
AFTER INSERT, UPDATE, DELETE
AS
set nocount on
begin try
declare @OldOptions int = @@OPTIONS
set xact_abort off
declare @IsDebug bit = 1
declare @CurrentDateTime datetime = getutcdate()
declare @TriggerMessage varchar(max), @TriggerId int
if @IsDebug = 1
begin
select @TriggerId = isnull(max(TriggerId), 0) + 1
from uManageDBLogs.dbo.tbl_TriggerLog
declare @dbcc_INPUTBUFFER table(EventType nvarchar(30), Parameters Int, EventInfo nvarchar(4000) )
declare @my_spid varchar(20) = CAST(@@SPID as varchar(20))
insert @dbcc_INPUTBUFFER
exec('DBCC INPUTBUFFER ('+@my_spid+')')
select @TriggerMessage = replace(EventInfo, '''', '''''') from @dbcc_INPUTBUFFER
insert into uManageDBLogs.dbo.tbl_TriggerLog (TriggerId, "Message", CreateDate)
values (@TriggerId, @TriggerMessage, @CurrentDateTime)
end
declare @Oper int
select @Oper = 0
-- determine type of sql statement
if exists (select * from inserted) select @Oper = @Oper + 1
if exists (select * from deleted) select @Oper = @Oper + 2
if @IsDebug = 1
begin
select @TriggerMessage = '@Oper = ' + convert(varchar, @Oper)
insert into uManageDBLogs.dbo.tbl_TriggerLog (TriggerId, "Message", CreateDate)
values (@TriggerId, @TriggerMessage, @CurrentDateTime)
end
if @Oper = 0 return -- No data changed
declare @TomorrowDate date = dateadd(day, 1, convert(date, getdate()))
declare @CurrentDate date = convert(date, getdate())
-- transactions from both inserted and deleted tables
declare @tbl_Trans table (FirmId int, GLAccountId int,
AmountDebit money, AmountCredit money, "Status" char(1), TableType char(1))
declare @tbl_AccountCounters table (FirmId int, GLAccountId int, Balance money)
declare @IsChange bit = null
insert into @tbl_Trans (FirmId, GLAccountId, AmountDebit, AmountCredit, "Status", TableType)
select FirmId, GLAccountId, AmountDebit, AmountCredit, "Status", 'I'
from inserted
union
select FirmId, GLAccountId, AmountDebit, AmountCredit, "Status", 'D'
from deleted
if @IsDebug = 1
begin
select @TriggerMessage = (select * from @tbl_Trans for xml path ('tbl_Trans'))
insert into uManageDBLogs.dbo.tbl_TriggerLog (TriggerId, "Message", CreateDate)
values (@TriggerId, @TriggerMessage, @CurrentDateTime)
end
insert into @tbl_AccountCounters (FirmId, GLAccountId, Balance)
select FirmId, GLAccountId, 0
from @tbl_Trans
group by FirmId, GLAccountId
if @Oper = 1 or @Oper = 2 -- insert/delete
begin
update @tbl_AccountCounters
set Balance = cnt.TransSum
from @tbl_AccountCounters as ac join
(
select trans.FirmId, trans.GLAccountId,
isnull(sum((trans.AmountDebit - trans.AmountCredit) * iif(trans.TableType = 'I', 1, -1)), 0) as TransSum
from @tbl_Trans as trans
where trans.Status = 'A'
group by trans.FirmId, trans.GLAccountId
) as cnt on ac.FirmId = cnt.FirmId and ac.GLAccountId = cnt.GLAccountId
select @IsChange = 1
end
else
begin
if update(AmountDebit) or update(AmountCredit) or update(Status) or update(GLAccountId)
begin
update @tbl_AccountCounters
set Balance = cnt.TransBalance
from @tbl_AccountCounters as ac join
(select trans.FirmId, trans.GLAccountId, isnull(sum(trans.AmountDebit - trans.AmountCredit), 0) as TransBalance
from dbo.tbl_GLTransaction as trans
where trans."Status" = 'A' and exists (select 1 from @tbl_AccountCounters as ac
where ac.GLAccountId = trans.GLAccountId and ac.FirmId = trans.FirmId)
group by trans.FirmId, trans.GLAccountId) as cnt on
ac.FirmId = cnt.FirmId and ac.GLAccountId = cnt.GLAccountId
select @IsChange = 0
end
end
if @IsDebug = 1
begin
select @TriggerMessage = '@IsChange = ' + isnull(convert(varchar, @IsChange), 'null')
insert into uManageDBLogs.dbo.tbl_TriggerLog (TriggerId, "Message", CreateDate)
values (@TriggerId, @TriggerMessage, @CurrentDateTime)
select @TriggerMessage = (select * from @tbl_AccountCounters for xml path ('tbl_AccountCounters'))
insert into uManageDBLogs.dbo.tbl_TriggerLog (TriggerId, "Message", CreateDate)
values (@TriggerId, @TriggerMessage, @CurrentDateTime)
end
if @IsChange is not null
begin
update tbl_GLAccount
set tbl_GLAccount.Balance = iif(@IsChange = 1, cnt.Balance + acc.Balance, cnt.Balance),
tbl_GLAccount.LastUpdate = getutcdate(),
tbl_GLAccount.LastUpdatedBy = 1
from @tbl_AccountCounters as cnt join dbo.tbl_GLAccount as acc on
cnt.FirmId = acc.FirmId and cnt.GLAccountId = acc.GLAccountId
end
if (16384 & @OldOptions) = 16384 set xact_abort on
end try
begin catch
declare @ErrorLine varchar(max)
select @ErrorLine = uManageDb.dbo.udf_GetErrorInfo()
insert into uManageDb.dbo.tbl_TriggerError ("Name", "Message", CreateDate)
values ('AccountingDB..trg_AccountBalance', @ErrorLine, GETUTCDATE())
end catch
答案 0 :(得分:0)
我想我已经找到了。我有这条线:
select .. from inserted
union
select .. from deleted
他们插入5 trans 300美元和4 trans 100美元。我的@tbl_Trans中有2条记录(300和100)(它在日志中)。那可能是错误。因此,记录hellps并触发必要的运行。
我会用union all替换union。