ASP.NET 4.6.2 MVC Web应用程序访问的SQL Server 2016
我有桌子"建筑"建筑物可以有多个组件"。例如,Building1具有Component1和Component2 ......等
我被要求能够锁定建筑物。锁意味着无法再修改组件(CREATE / UPDATE / DELETE)。好吧,你可以想象,这是一个巨大的应用程序,一个组件可以在100多个地方修改。没人能回答这个问题,"我需要锁定哪里?"。
我的想法是锁定我能想到的任何地方然后作为安全网创建一个SQL触发器,如果组件表上的列" IsLocked BIT"是真的。目前,我知道组件是否被锁定的唯一方法是IsLocked列是否等于true。
所以,我为此说了所有这些。如果正在修改的行具有列IsLocked = 1,如何创建一个SQL Server触发器,以防止修改一行数据?
修改1 在我看来,这不是重复。使用而不是删除或代替...将不适合我。如果我这样做而不是......那么我需要提供提交逻辑。我不想提供提交逻辑。我只想在插入,更新,删除之前运行检查。
编辑2 - 而不是更新/删除是最佳选择 如果不是......是我最好的选择,有人可以使用而不是更新/删除重写我所拥有的内容吗?我不知道该怎么做。请记住,请求将来自网络应用程序。我不知道他们是在更新一个列还是整个实体或他们将传入的内容。我知道我写的方式是它会捕获任何插入/更新/删除并阻止它被锁定。如果有更好的方法,那么请写下来并解释为什么它会更好。
答案 0 :(得分:0)
以下是我提出的解决方案:
ALTER TRIGGER [dbo].[PreventLockedModification]
ON [dbo].[Component]
FOR INSERT, UPDATE, DELETE
AS
BEGIN
SET NOCOUNT ON;
--DETERMINE INSERT(I) UPDATE(U) OR DELETE(D)
----------------------------------------------------------------------------------------------------
DECLARE @action as char(1);
SET @action = 'I'; -- Set Action to Insert by default.
IF EXISTS(SELECT * FROM DELETED)
BEGIN
SET @action =
CASE
WHEN EXISTS(SELECT * FROM INSERTED) THEN 'U' -- Set Action to Updated.
ELSE 'D' -- Set Action to Deleted.
END
END
----------------------------------------------------------------------------------------------------
DECLARE @ErrorMsg nvarchar(100) = 'This row is locked and cannot be updated';
DECLARE @IsLocked bit;
DECLARE @BuildingId bigint;
DECLARE @UnitId bigint;
DECLARE @IsComplete_Building bit;
DECLARE @IsComplete_Unit bit;
----------------------------------------------------------------------------------------------------
IF @action = 'U' or @action = 'D'
BEGIN
SELECT @IsLocked = IsLocked FROM deleted;
IF @IsLocked = 1
BEGIN
RAISERROR (@ErrorMsg, 16, 1);
ROLLBACK TRANSACTION
END
END
----------------------------------------------------------------------------------------------------
ELSE IF @action = 'I'
BEGIN
SELECT @BuildingId = BuildingId FROM inserted;
SELECT @UnitId = UnitId FROM inserted;
SELECT @IsComplete_Building = IsComplete FROM Building WHERE BuildingId = @BuildingId
SELECT @IsComplete_Unit = IsComplete FROM Unit WHERE UnitId = @UnitId
IF @IsComplete_Building = 1 or @IsComplete_Unit = 1
BEGIN
RAISERROR (@ErrorMsg, 16, 1);
ROLLBACK TRANSACTION
END
END
----------------------------------------------------------------------------------------------------
END