Sybase ASE 15.7 中的审计触发器 Table

Trigger for Audit Table in Sybase ASE 15.7

我正在尝试创建一个触发器来记录有关插入、更新和删除的信息。为了简单起见,我只是想创建一个插入触发器,而不包括用户和日期等信息。

我引用的 table 包含以下列:

默认属性

-默认属性 ID

-Key_

-值

-ProcessID_FK(外键)

==============================

我的审计 table 是:

DefaultProperties_Audit

-OldDefaultID

-OldKey_

-旧值

-OldProcessID_FK

我当前触发器的代码是:

create trigger DPTrigger on DefaultProperties
   for insert as
   begin
       insert into DefaultProperties_Audit(OldDefaultID, OldKey_, OldValue, OldPid_FK, Modifier, EntryDate, Operation)
       select DefaultPropertiesID, Key_, Value, ProcessID_FK, user_name(), GETDATE(), 'insertion' from inserted
   end

但是我该怎么做呢?

create trigger DPTrigger on DefaultProperties
    for insert, update, delete as
    if insert then
        begin
            insert into DefaultProperties_Audit(OldDefaultID, OldKey_, OldValue, OldPid_FK, Modifier, EntryDate, Operation)
            select DefaultPropertiesID, Key_, Value, ProcessID_FK, user_name(), GETDATE(), 'insertion' from inserted
        end
    endif
    if update then
        doSomething()
    endif
    if delete then
        doSomethingElse()
    endif

当我尝试编译我的上述版本时,它抛出一个错误。我知道另一种方法是为插入、更新和删除创建三个单独的触发器。我只是想知道我是否可以将它浓缩成一个?

此外,如果我明确说明,我似乎可以将其浓缩为一个 如果更新(col1)或更新(col2)或更新(col3) 但这似乎也可能带来一些错误。

任何 tips/hints 使这项工作和改进它都将 非常感谢

ASE触发器支持update()功能;没有 insert() 函数这样的东西。

虽然 update() 函数可用于插入触发器,但 update() 通常用于更新触发器以确定哪些列已被更新。

在这种特殊情况下,由于您计划将整行插入审计 table,显然(?)所有列都是新的,您可能会发现如下所示更有用:

create trigger dbo.DPTrigger on dbo.DefaultProperties
    for insert as
    begin
        insert into DefaultProperties_Audit(OldDefaultID, OldKey_, OldValue, OldPid_FK)
        select DefaultPropertiesID, Key_, ProcessID_FK, Value from  inserted
    end

有关 create trigger 语法、示例和触发编码的一些讨论,请参阅 ASE - Reference Manual: Commands - create trigger

有关触发器使用的更多讨论,因为它与 RI 和事务控制有关,请参阅 ASE - TSQL Users Guide - Triggers: Enforcing RI constraints


至于询问有关将 insert/update/delete 代码整合到单个触发器中的更新问题...

确定触发器是否在插入、更新或删除时触发的最简单方法是测试伪table 中是否存在名为 inserted 和 [=18= 的行];您可以在每次触发器需要知道父 DML 的类型时测试是否存在,或者测试一次并存储在 @variable:

create trigger ...
begin
    declare @operation char(1) -- 'I'nsert, 'U'pdate, 'D'elete
    if exists(select 1 from inserted)
        select @operation = 'I'
    if exists(select 1 from deleted)
        select @operation = case when @operation = 'I' then 'U' else 'D' end

    ... reset of trigger code ...
end