0

私のデータベースには、変更を追跡する列がいくつかあります。A、B、C列を作成しましょう。ユーザーと管理者は、これらの列の値を変更できます。セル値(列、行)が管理者によって変更された場合、ユーザーはそれを変更できないようにする必要があります。

これを解決するために、行ID、列ID、ユーザー変更のフィールドを持つセル変更のログテーブルを維持することを考えています。

注:SQL Server 2008、C#を使用しています。

私の考えについてコメントしてください。ありがとう。

4

1 に答える 1

1

SQL Serverは、列を最後に変更したユーザーに関する情報を保持しません。したがって、INSTEADOFまたは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;

(履歴を維持したい場合を除いて、別のテーブルを使用するのはやり過ぎのようです。)

これで、ルールに従うINSTEADOFトリガーを使用できます。袖口からの大まかなアイデア:

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
于 2012-04-17T16:18:22.140 に答える