私のデータベースには、変更を追跡する列がいくつかあります。A、B、C列を作成しましょう。ユーザーと管理者は、これらの列の値を変更できます。セル値(列、行)が管理者によって変更された場合、ユーザーはそれを変更できないようにする必要があります。
これを解決するために、行ID、列ID、ユーザー変更のフィールドを持つセル変更のログテーブルを維持することを考えています。
注:SQL Server 2008、C#を使用しています。
私の考えについてコメントしてください。ありがとう。
私のデータベースには、変更を追跡する列がいくつかあります。A、B、C列を作成しましょう。ユーザーと管理者は、これらの列の値を変更できます。セル値(列、行)が管理者によって変更された場合、ユーザーはそれを変更できないようにする必要があります。
これを解決するために、行ID、列ID、ユーザー変更のフィールドを持つセル変更のログテーブルを維持することを考えています。
注:SQL Server 2008、C#を使用しています。
私の考えについてコメントしてください。ありがとう。
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