删除审计表的触发器

时间:2016-07-04 19:43:23

标签: sql-server triggers audit

我正在开发一个在SQL Server数据库中的某些表上执行CRUD操作的Web应用程序。应用程序中将有一个记录用户执行这些操作。

(顺便说一下,我正在使用实体框架)

假设表格是

MyTable的

  • MyTableId
  • SomeColumn
  • LastModifiedUserId
  • LastModifiedDate

我有一个像

这样的审计表

MyTableHistory

  • MyTableHistoryId
  • MyTableId
  • SomeColumn
  • ActionType --ins / upd / del
  • ActionUserId
  • ActioDate

我正在使用触发器在审计表上插入数据。

通过查阅Inserted和Updated表来查找修改记录的用户ID,可以轻松进行插入和更新。

但是删除呢?知道如何获得这些信息吗?

2 个答案:

答案 0 :(得分:0)

没有updated表这样的东西。 DML触发器中可用的两个伪表是inserteddeleted。在insertdeleted为空的情况下,如果deleteinserted为空,则在update的情况下填充两个表。
您可以为每个操作创建三个单独的触发器(以区分ActionType)或尝试将所有操作组合在一个触发器中 注意:考虑多行操作。

答案 1 :(得分:0)

假设您使用EF添加有关哪个用户正在更新记录的信息,捕获该信息的最简单方法是让EF对您要删除的数据执行两步处理(UPDATE,DELETE)。然后,您需要将两个审计行解释为同一操作的一部分。

有一个更复杂的解决方案“可能”有效,但我还没有测试过。如果您想探索它,可以在下面找到更多信息。

另一个选择是放弃触发审计(由于这个原因,这是有问题的)并改为使用实体框架。下面是一个如何通过覆盖SaveChanges方法来实现此目的的示例:

public virtual IEnumerable<System.Data.Entity.Infrastructure.DbEntityEntry> ChangedEntries()
{
    return ChangeTracker.Entries().Where(x =>
        x.State == EntityState.Added ||
        x.State == EntityState.Deleted ||
        x.State == EntityState.Modified);
}

public virtual int SaveChanges(string userName)
{
    var changes = ChangedEntries();

    foreach (var entry in changes)
    {
        var eventType = entry.State == EntityState.Added ? "A" : entry.State == EntityState.Deleted ? "D" : "U";
        var entityType = ObjectContext.GetObjectType(entry.Entity.GetType()).Name;

        var oldValues = entry.State == EntityState.Added ? null : JsonConvert.SerializeObject(entry.OriginalValues.ToObject());
        var newValues = entry.State == EntityState.Deleted ? null : JsonConvert.SerializeObject(entry.CurrentValues.ToObject());

        oldValues = oldValues?.Substring(0, Math.Min(oldValues.Length, 4000));
        newValues = newValues?.Substring(0, Math.Min(newValues.Length, 4000));

        AuditItems.Add(
            new AuditItem
            {
                EventTime = DateTime.Now,
                UserName = userName,
                EntityType = entityType,
                EventType = eventType,
                OldValues = oldValues,
                NewValues = newValues
            }
        );
    }

    return base.SaveChanges();
}