Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sql-server-2005/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 2005 审核触发器:使用插入或删除的系统表_Sql Server 2005_Audit_Auditing_Audit Tables - Fatal编程技术网

Sql server 2005 审核触发器:使用插入或删除的系统表

Sql server 2005 审核触发器:使用插入或删除的系统表,sql-server-2005,audit,auditing,audit-tables,Sql Server 2005,Audit,Auditing,Audit Tables,如何审核表的主题最近在我们的讨论中突然出现。。。所以我喜欢你关于什么是最好的方法的意见。我们的数据库中混合了这两种方法(这并不好),因为之前的每位DBA都做了他/她认为正确的事情。因此,我们需要改变它们,使之遵循任何一种模式 CREATE TABLE dbo.Sample( Name VARCHAR(20), ... ... Created_By VARCHAR(20), Created_On DATETIME, Modified_By VARCHAR(20), Modified_On DATE

如何审核表的主题最近在我们的讨论中突然出现。。。所以我喜欢你关于什么是最好的方法的意见。我们的数据库中混合了这两种方法(这并不好),因为之前的每位DBA都做了他/她认为正确的事情。因此,我们需要改变它们,使之遵循任何一种模式

CREATE TABLE dbo.Sample(
Name VARCHAR(20),
...
...
Created_By VARCHAR(20),
Created_On DATETIME,
Modified_By VARCHAR(20),
Modified_On DATETIME
)

CREATE TABLE dbo.Audit_Sample(
Name VARCHAR(20),
...
...
Created_By VARCHAR(20),
Created_On DATETIME,
Modified_By VARCHAR(20),
Modified_On DATETIME
Audit_Type VARCHAR(1)  NOT NULL
Audited_Created_On DATETIME
Audit_Created_By VARCHAR(50)
)
方法1:在审计表中,仅存储从主表中替换/删除的记录(使用系统表删除)。因此,对于主表中的每次更新和删除,将被替换的记录插入到审计表中,其中“audit_Type”列为wither“U”(用于更新)或“D”(用于删除)

插入未经审核。对于任何记录的当前版本,始终查询主表。对于历史记录,您可以查询审计表

优点:似乎很直观,可以存储以前版本的记录 缺点:如果需要了解特定记录的历史记录,则需要将审核表与主表连接起来

Appraoch 2:在审计表中存储进入主表的每条记录(使用插入的系统表)

插入/更新/删除到主表的每条记录也存储在审核表中。所以,当您插入一条新记录时,它也会被插入到审计表中。更新时,新版本(从插入的)表存储在审核表中。删除时,旧版本(来自已删除)表存储在审核表中

优点:如果你需要知道某一特定记录的历史,你可以把所有的东西都放在一个地方


虽然我没有在这里列出所有的方法,但每种方法都有其优缺点?

我们经常使用的第三种方法是只审核感兴趣的列,并在每行保存“新”和“旧”值

因此,如果您有“name”列,审计表将有“name\u old”和“name\u new”

在插入触发器中,“name_old”根据您的偏好设置为空白/空,而“name_new”则从INSERTED设置。 在更新触发器中,“name_old”是从DELETED设置的,而“name_new”是从INSERTED设置的 在删除触发器中,“name_old”从DELETED和“new_name”设置为blank/null

(或者对所有情况使用完全联接和一个触发器)

对于VARCHAR字段,这看起来可能不是一个好主意,但是对于INTEGER、DATETIME等,它提供了一个很容易看到更新差异的好处

也就是说,如果您在实际表中有一个数量字段,并将其从5更新为7,则在审计表中有:

quantity_old  quantity_new
           5             7
您可以很容易地计算出数量在特定时间增加了2

如果审计表中有单独的行,则必须将一行与“下一行”连接起来,以计算差异-在某些情况下,这可能很棘手…

我同意:

Appraoch 2:在审计表中存储进入主表的每条记录 (使用插入的系统表)

每个项目多出一行真的会毁掉数据库吗?这样你们就有了完整的历史

如果清除行(一个早于X天的范围),您仍然可以判断是否有更改:

  • 如果存在审核行(未清除),则可以查看相关行是否已更改
  • 如果该项不存在审核行(全部已清除),则不会发生任何更改(因为任何更改都会写入审核表,包括全新的项)

如果使用Appraoch 1:并清除一个范围,则很难(需要记住清除日期)区分新插入和清除所有行的插入。

感谢您的回复。我以前听说过这种方法,但从未实施过。我会进一步考虑的。谢谢,在我把我所有的想法写进这个问题/帖子并重新阅读之后,我也有同样的想法。方法2似乎更好。小的头顶可以忽略不计。谢谢你的意见。