触发器没有运行?

时间:2017-10-27 11:42:16

标签: sql-server

插入/更新/删除/“后,我有一个触发器”。它应该根据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

1 个答案:

答案 0 :(得分:0)

我想我已经找到了。我有这条线:

select .. from inserted 
union 
select .. from deleted

他们插入5 trans 300美元和4 trans 100美元。我的@tbl_Trans中有2条记录(300和100)(它在日志中)。那可能是错误。因此,记录hellps并触发必要的运行。

我会用union all替换union。