跟踪在 C# 应用程序或 SQL Server 中对 SQL Server 进行更改的人员

Posted

技术标签:

【中文标题】跟踪在 C# 应用程序或 SQL Server 中对 SQL Server 进行更改的人员【英文标题】:Tracking who makes changes to SQL Server within C# application or SQL Server 【发布时间】:2015-01-31 09:31:26 【问题描述】:

我正在将应用程序从 Access 转换为 SQL Server 2014。此工具的功能之一是允许用户创建临时 SQL 查询来修改删除或向多个表添加数据。

目前在 Access 中无法跟踪谁做了什么,所以如果某事因意外而搞砸了,就无法知道它是谁或何时发生(它发生的次数足够多,这是一个严重的问题,并且重写工具的众多原因之一)。

我正在编写的应用程序是 C# 中的 Windows 应用程序。我正在寻找有关如何在不对服务器(处理或空间)提出巨大需求的情况下完成此操作的任何和所有建议。由于用户正在创建自己的查询,我不能只为用户名和日期添加一列(这也只会跟踪最近的更改)。

我们不需要保留旧数据,甚至不需要准确识别更改的内容。只是谁更改了数据以及何时更改。我希望能够查看一些内容(视图、表格甚至单独的数据库),这些内容向我显示了进行更改的用户列表以及他们何时进行更改。

【问题讨论】:

从 2008 版本开始,SQL Server 中有一个内置机制,即更改数据捕获 (CDC),它就是这样做的。它还会向您展示到底发生了什么变化。 从我目前所阅读的所有内容来看,CDC 并未捕获进行更改的用户名。此外,我不需要保留所有更改。这可能会导致数据库比我想要的要大得多。 您如何处理对 c# 应用程序中数据库的访问?单一 userId 还是 Windows 身份验证(意味着每个用户都有一个数据库帐户)? Access 数据库没有开启任何安全功能,因此任何人都可以打开它们,C# 应用程序也不必担心。 【参考方案1】:

您尚未指定 SQL Server 版本,无论如何,如果您的版本 >= 2008 R2,您可以使用Extended Events 来监控您的系统。

在 *** 上,您可以阅读 my answer 来解决类似问题

【讨论】:

我确实说过我要去 SQL Server 2014。这些扩展事件在那个版本中仍然可用还是已被删除? 对不起...是的,所有版本都可用(包括快递版)【参考方案2】:

您可以考虑使用触发器和日志表,这将适用于所有 SQL Server。触发器比 CDC 贵一点,但如果您的用户已经直接在您的表上进行更新,这应该不是问题。我认为这也取决于您要记录多少表。

我将为您提供一个简单的示例,用于记录更改了一个表或多个表的用户(只需将触发器添加到表中):

CREATE TABLE UserTableChangeLog
(
    ChangeID INT PRIMARY KEY IDENTITY(1,1)
    , TableName VARCHAR(128) NOT NULL
    , SystemUser VARCHAR(256) NOT NULL DEFAULT SYSTEM_USER
    , ChangeDate DATETIME NOT NULL DEFAULT GETDATE()
)

GO

CREATE TABLE TestTable
(
    ID INT IDENTITY(1,1)
    , Test VARCHAR(255)
)

GO
--This sql can be added for multiple tables, just change the trigger name, and the table name
CREATE TRIGGER TRG_TABLENAME_Log ON TestTable
AFTER INSERT, UPDATE, DELETE
AS
BEGIN
    SET NOCOUNT ON;

    --Can be used to get type of change, and wich data that was altered. 
    --SELECT * FROM INSERTED;
    --SELECT * FROM DELETED;

    DECLARE @tableName VARCHAR(255) = (SELECT OBJECT_NAME( parent_id ) FROM sys.triggers WHERE object_id =  @@PROCID);

    INSERT INTO UserTableChangeLog (TableName) VALUES (@tableName);

END

GO

这就是它的工作方式:

INSERT INTO TestTable VALUES ('1001');
INSERT INTO TestTable VALUES ('2002');
INSERT INTO TestTable VALUES ('3003');
GO

UPDATE dbo.TestTable SET Test = '4004' WHERE ID = 2

GO

SELECT * FROM UserTableChangeLog

【讨论】:

这也许是我最终不得不做的,但我听说触发器确实会影响性能。 @Spots Knight:这取决于触发器,如果​​您在触发器中运行一些“昂贵”的查询,它会在触发时显着影响您的性能,因为您必须等待它完成。在您可能在短时间内有数百或数千个不同的 UPDATE/INSERT/DELETE 查询的情况下,我也会重新考虑不使用触发器。然而,在这个例子中,它不会比额外的“单行插入”使用更多的性能,甚至很难测量。

以上是关于跟踪在 C# 应用程序或 SQL Server 中对 SQL Server 进行更改的人员的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 c# 监控 SQL Server 表更改?

如何使用 c# 监控 SQL Server 表更改?

如何创建跟踪 (SQL Server Profiler)

如何在 SQL Server 中找到正在运行的跟踪?

运行SQL Server Profiler的时候,提示“您必须是 sysadmin 固定服务器角色的成员或具有 ALTER TRACE 权限,才能对 SQL Server 运行跟踪。”

如何在 C# 或 SQL Server 中找到邮政编码之间的距离?