2016-10-05 150 views
0

我有一个典型的web应用程序,非常基于CRUD。当某些表或列发生更改时,我们需要存储关于它的历史信息。这可以例如是一个包含新/旧列值,时间戳,相关表格,改变它的用户名称等的审计表。SQL Server 2016审计功能

通常我已经实现了这个例如用触发器获取这些信息并存储到审计表。

但是,使用SQL Server 2016审计功能可以自动实现吗?我想到了几个问题: 1)它能够将审计数据存储在数据库表中,就像上面的触发器示例一样? 2)是允许读取数据的应用程序,还是访问经审核的数据需要一些特殊的管理员凭据? 3)是否可以指定需要记录哪些信息,或者功能是否自动记录所有内容?

+0

这是数据*审计*或*历史*的目的?对于历史,您可能需要考虑新的时态表特征,如果这符合。 –

+0

我认为历史和审计是一回事。关键点是1)我们可能需要能够定义表结构,2)应用程序页面需要能够查询审计/临时表格 – user1340582

+0

对于历史表格,Damien提供的最佳方式是使用Temporal表格http://SQL Server 2016上的/www.kodyaz.com/sql-server-2016/create-sql-server-2016-temporal-table.aspx。不幸的是,这些表没有导致更改的用户名 – Eralper

回答

0

可以使用触发器来跟踪数据变化对数据库表 您可以称之为教程

在这里,你需要知道找到如何log sql table data changes using triggers的例子,如果你的应用程序的用户映射到数据库上的单个用户,您必须在您的UPDATE,DELETE或INSERT命令中明确地将用户信息插入,更新或删除,作为表字段值。否则,你将得到的将是所有交易

就如T emporal tables on SQL Server 2016相同的用户,你需要使用或创建历史表或登录表手动

请检查下面的SQL触发代码

CREATE TRIGGER dbo.LogTbl 
    ON dbo.Tbl 
AFTER INSERT, UPDATE, DELETE 
AS 

IF EXISTS (
    SELECT * FROM Inserted 
) -- INSERT or UPDATE 
BEGIN 
    IF EXISTS (
     SELECT * FROM Deleted 
    ) 
    -- UPDATE Statement was executed 
    INSERT INTO HistoryTbl (
    ... 
    UpdatedDate, 
    UpdatedByUserId 
) 
    SELECT 
    ... 
    i.UpdatedDate, 
    i.UpdatedByUserId 
    FROM Deleted d 
    INNER JOIN Inserted i ON i.Id = d.Id 

    ELSE 
    -- INSERT Statement was executed 
    INSERT INTO HistoryTbl (
    ... 
    InsertedDate, 
    InsertedByUserId 
) 
    SELECT 
    ... 
    i.InsertedDate, 
    i.InsertedByUserId 
    FROM Inserted i 

END 
ELSE 
    -- DELETE Statement was executed 
    INSERT INTO HistoryTbl (
    ... 
    DeletedDate, 
    DeletedByUserId 
) 
    SELECT 
    GETDATE(), ---!!! 
    USER_ID() ---!!! 
    FROM Deleted 

GO 

注意DELETE命令,在删除命令中我们没有删除用户数据。因此我使用了USER_ID(),您也可以使用USER_NAME()。

另一种方法是,可以不删除行,而是通过将ACTIVE列值更新为false来删除它。我的意思是更新数据,它将其活动字段设置为0,这可以被认为是它被删除。

所以你必须修改所有的代码,只选择活动的数据...

+0

是触发器是一种方法我之前使用过它,但是现在我想知道我们是否可以使用SQL Server 2016功能来支持这个开箱即用的功能?触发器会导致各种性能问题和混乱... – user1340582