2014-04-29 24 views
0

符合下表:如何跟踪由Microsoft SQL Server中的存储过程引起的更改流?

CREATE TABLE [Test] 
(
    [Id] BIGINT IDENTITY NOT NULL, 
    [Name] CHARACTER VARYING(255) NOT NULL, 
    [Description] CHARACTER VARYING(MAX) NOT NULL, 

    PRIMARY KEY([Id]) 
); 

我控制的新记录创建与存储过程:

CREATE PROCEDURE [Test_Create] 
    @SessionId BINARY(32), 
    @Name CHARACTER VARYING(255), 
    @Description CHARACTER VARYING(MAX) 
AS 
BEGIN 
    BEGIN TRANSACTION; 
     BEGIN TRY 
      INSERT INTO [Test] ([Name], [Description]) 
      VALUES (@Name, @Description); 
     END TRY 
     BEGIN CATCH 
      ROLLBACK TRANSACTION; 
      THROW; 
     END CATCH 
    COMMIT TRANSACTION; 
END 

我有一个触发器,只需登录前后的值这个表,对所有变化。当我调用存储过程时,会触发此触发器并记录到另一个表。但是,我的触发器显然不能使用@SessionId变量记录哪个网站用户会话导致存储过程被运行在Web服务器上的SQL客户端调用。我不想使用SET CONTEXT_INFO,因为它在连接池和并行执行计划中不稳定。这就是说,我认为我可以将传入存储过程的@SessionId@@SPID值关联起来,但这对连接池又有点棘手。据我所知,它不起作用。

我如何跟踪我的网站,该网站的用户,假设我对他们有一个唯一的会话数传递到我的存储过程,引起我的任何表的具体变化?

如果他们调用存储过程,我需要知道调用存储过程以及它是如何变更的表(之前和值后)。

是否有替代方法检索以下信息将它们链接在一起形成审核跟踪?

  • 网站用户/会话导致存储的过程被调用被调用
  • 将所得数据之前和之后的查询
  • 查询(的效果
  • 存储的过程和它的参数数据)
+0

你不能只将日志记录添加到'Test_Create'本身? – David

+0

@David如果我这样做了,那么我需要为每个插入,更新或删除操作写入日志条目,然后再计算出旧值。这会增加很多额外的代码,可以通过触发来解决。我认为最好找出如何将来自存储过程上下文的'@ SessionId'和触发器上下文中的@@ SPID关联起来。 –

回答

0

我会建议您修改表结构,使@SessionId值存储在表中创建和修改。

我有一个ASP。网络应用程序,也必须登录用于审计的所有变化,以及需要审计都有

CreatedDateTime DateTime NOT NULL 
CreatedBy nvarchar(50) NOT NULL 
ModifiedDateTime DateTime NULL 
ModifiedBy nvarchar(50) NULL 

用户登录使用Windows身份验证的表,我们将用户的domain\username所有存储的特效以便它可以存储在CreatedByModifiedBy栏中。 CreatedDateTime/ModifiedDateTime值由存储的过程设置。

我们的更改日志审计由CLR触发器完成,该触发器仅提取新记录中的ModifiedBy值,并将其记录为发生更改的人员。

使用你的@SessionId值将工作,我会想。

+0

UserA修改记录然后UserB修改记录时会发生什么?您的设计不支持审计跟踪,只支持“最新”方法。 –

+0

对不起,我不清楚。虽然实际的表只显示最后一个更改记录的人(这对于显示而言很有用)。审计触发器通过记录用户/更改日期/表名/字段名称来记录到单独的审计数据库/表中的每个字段/旧值/新值。因此,如果用户在一次更新中更改了20个字段,那么日志表中将有20行显示发生了什么。 – DeanOC

+0

除了我最后的评论之外,这对我们来说在过去7年中表现良好,并且允许我们在必要时恢复更改,并且还执行侦探工作来解决错误或验证/否认用户的声明“我没有去做!”。唯一的缺点是我们的审计表现在使真正的数据库变得渺茫。 – DeanOC

0

我的第一个问题是 “为什么”?

基于潜在的答案有几个选项:

如果你只是好奇,并希望做一些调查问题,你可以使用SQL Server Profiler或数据库引擎跟踪捕获和跟踪重播时正确记录事件。这会告诉你确切的哪些程序被调用,为什么用户和正确的参数。

如果您想立即使用这些信息进行管理报告,我建议你将它传递到您的存储过程,并将其存储在一个表格中,您可以根据需要询问它。

如果您希望在未来的某个时间使用这些信息,您可以在数据访问层上打开日志记录,以便将查询前后的信息存储在日志文件中或存储在数据库中,如果您确实想要。

+0

目的是为了安全审计和恢复。我们需要知道我们网站上的哪个用户更改了一些数据。我们正试图为恶意用户删除大量内容而构建恢复功能,并且我们需要暂停用户,然后仅回滚他们所做的并在交火中捕获任何合法编辑/添加。我们希望尽可能多地控制数据库中的原因是因为我们已经分散了这个系统的一部分;许多可信的客户端连接到SQL Server实例并代表其用户群进行更改。 –

+0

在这种情况下,我会选择上面的中间选项。为可用于回滚更改的表创建审计表。有很多方法可以做到这一点。可以用审计表镜像表结构,但这是相当脆弱的。您可以创建更通用的结构,并在您通过触发器进行更新时进行更新。属性(ID,名称,说明),PropertyChanges(ID,PropertyIdChanged,UserId,更改日期,ValueBefore,ValueAfter)。这对审计很有好处,但需要仔细考虑使用它来恢复数据。可能还有其他解决方案! – sarin

+0

因此,我尝试了触发器方法并添加了属性更改以及所有这些。我甚至让它回滚。我在触发器中遇到的困难是,除了在我的问题中提到的'SET CONTEXT_INFO'外,我无法将'@ SessionId'与触发器进行通信。 –

相关问题