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
关于将插入/更新/删除代码合并到单个触发器中的更新问题...
确定触发器是否在插入、更新或删除时触发的最简单方法是测试名为inserted
和deleted
的伪表中是否存在行;您可以在每次触发器需要知道父 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 中的审计表触发器的主要内容,如果未能解决你的问题,请参考以下文章