【问题标题】:track database field change - sql server跟踪数据库字段更改 - sql server
【发布时间】:2012-04-17 16:09:11
【问题描述】:

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

为了解决这个问题,我正在考虑为带有字段的单元格更改维护一个日志表 - 行 ID、列 ID、用户已更改。

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

请评论我的想法。谢谢。

【问题讨论】:

    标签: sql-server-2008 entity-framework c#-4.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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-04-16
      • 2017-09-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多