跟踪数据库字段更改 - sql server

时间:2012-04-17 16:09:11

标签: sql-server-2008 entity-framework c#-4.0

在我的数据库中,我有几列要跟踪其更改。我们有A,B和C列。用户和管理员可以更改这些列中的值。如果管理员更改了单元格值(列,行),则用户无法更改它。

为了解决这个问题,我想维护一个用于单元格更改的日志表,其中包含字段 - 行ID,列ID,用户已更改。

注意:我使用的是Sql Server 2008,C#。

请评论我的想法。谢谢。

1 个答案:

答案 0 :(得分:1)

SQL Server不会保留有关最后更改列的人员的信息。因此,您需要使用INSTEAD OF或AFTER触发器自行跟踪此信息。如果用户尝试更新A列和B列,您还需要确定要执行的操作,但管理员仅更新了A列 - 您是否希望允许用户更新B列,或者他们的整个更新是否失败? ?

您可以在表格中添加一列,指示每列的ChangedByAdmin:

ALTER TABLE dbo.MyTable ADD A_ChangedByAdmin BIT NOT NULL DEFAULT 0;
ALTER TABLE dbo.MyTable ADD B_ChangedByAdmin BIT NOT NULL DEFAULT 0;
ALTER TABLE dbo.MyTable ADD C_ChangedByAdmin BIT NOT NULL DEFAULT 0;

(除非你想保留历史记录,否则使用单独的表似乎有些过分。)

现在您可以拥有符合规则的INSTEAD OF触发器。袖带上的一个粗略的想法:

CREATE TRIGGER dbo.Update_MyTable
FOR dbo.MyTable
INSTEAD OF UPDATE
AS
BEGIN
  SET NOCOUNT ON;

  DECLARE @a BIT = CASE USER_NAME() WHEN 'Administrator' THEN 1 ELSE 0 END;

  IF UPDATE(A)
  BEGIN
    UPDATE t
      SET A = i.A, A_ChangedByAdmin = @a
      FROM dbo.MyTable AS t
      INNER JOIN inserted AS i
      ON t.key = i.key
      INNER JOIN deleted AS d
      ON i.key = d.key
      AND i.A <> d.A -- why bother if the value is the same
      WHERE (@a = 1 OR d.A_ChangedByAdmin = 0);
  END
  -- repeat for B and C

  -- then update the unrestricted columns:
  UPDATE t SET D = i.D, E = i.E --, etc.
    FROM dbo.MyTable AS t
    INNER JOIN inserted AS i
    ON t.key = i.key;
END
GO