Sybase ASE 15.7 中的审计表触发器

Posted

技术标签:

【中文标题】Sybase ASE 15.7 中的审计表触发器【英文标题】:Trigger for Audit Table in Sybase ASE 15.7 【发布时间】:2017-12-09 06:21:17 【问题描述】:

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

我引用的表是带有列的:

默认属性

-DefaultPropertiesID

-Key_

-值

-ProcessID_FK(外键)

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

我的审计表是:

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) 但这似乎也可能带来一些错误。

任何使这项工作和改进它的提示/提示将不胜感激

【问题讨论】:

能否更新您的问题以包括您正在使用的 Sybase 产品(ASE、SQLAnywhere、IQ、Advantage)以及版本? 您可能还想回顾您过去的问题,着眼于通过投票和/或接受有助于解决您的问题/问题的答案来提供反馈;当然,这主要是一堆游戏化,但有些人可能会选择将时间花在更有可能获得反馈的问题上 @markp 感谢您的反馈!产品/版本是: Adaptive Server Enterprise/15.7 【参考方案1】:

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

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

在这种特殊情况下,由于您计划将整行插入到您的审计表中,并且显然 (?) 所有列都是新的,您可能会发现以下内容更有用:

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


关于将插入/更新/删除代码合并到单个触发器中的更新问题...

确定触发器是否在插入、更新或删除时触发的最简单方法是测试名为inserteddeleted 的伪表中是否存在行;您可以在每次触发器需要知道父 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

【讨论】:

感谢您的帮助,我必须执行上述操作才能使其正常工作(请参阅原始问题)。但是,当我在 DefaultProperties 表中插入一行时,出现此错误 --> 错误从行开始:命令中的 1 - 插入 DefaultProperties (Key_, ProcessID_FK, Value) 值 ('k1', 1, 'v1' ) 命令行错误:1 列:1 错误报告 - SQL 错误:表 DefaultProperties_Audit 中的列 OldKey_ 不允许空值。 为什么要对DefaultProperties_Audit 表进行 4 次单独插入?你真的想在DefaultProperites_Audit 中为插入DefaultProperties 的每1 行创建4 个单独的行吗?如果您真的想要 4 个不同的行,那么您必须将 DefaultProperties_Audit 中的所有列定义为 NULL 确保它们具有默认值。 啊有道理。但是当我尝试你写的内容时,我收到了这个错误:错误从第 1 行开始 - 在 dbo.DefaultProperties 上创建触发器 dbo.DPTrigger 以作为开始插入 DefaultProperties_Audit(OldDefaultID, OldKey_, OldValue, OldPid_FK ) 从插入的结尾错误报告中选择 (DefaultPropertiesID, Key_, ProcessID_FK, Value) - ',' 附近的语法不正确。 *arg* 我已经剪切并粘贴了您的原始代码...忘记从select 的列列表中删除括号;我已经更新了我的答案......现在试试吧 它有效!精彩的。最后一件事哈哈,请看原帖

以上是关于Sybase ASE 15.7 中的审计表触发器的主要内容,如果未能解决你的问题,请参考以下文章

sybase ase 怎样修改表的所有者

sybase15.7自定义安装图形界面化管理工具怎么装

Sybase插入一个空格代替空字符串''

Propel 1.6 从 Sybase 15.7 生成模式有一些麻烦

SYBASE ASE上排查问题自定义存储过程

如何在 SAP ASE Sybase 16 中从具有外键的表中删除行