我想在SQL Server中创建一个触发器,如果某行中的某个特定字段已经包含NON-NULL值,则该触发器将阻止对该行进行更新。
然后它应该只是回滚更新。
背景:如果设置了onceChangedDate
,它将无法更改或再次将其置空。
表格结构:
ID, UserName, Hidden, ChangedOneDate
每个条目在创建时通常具有:
ID, SomeUser, 0, NULL
我有一个触发器,它将把CCD_;隐藏的"设置为1。
然后我想防止将来对ChangedOnceDate
进行任何更改。
我怎样才能做到这一点?
这有点像暗箭伤人,但看起来像是EXISTS
,其中deleted
伪表中的列的值不是NULL
,而是在inserted
伪表中
--Sample Table
CREATE TABLE dbo.YourTable (ID int IDENTITY(1,1),
SomeColumn varchar(10) NOT NULL,
NullableDate date NULL,
CONSTRAINT PK_YourTable PRIMARY KEY (ID));
GO
--Trigger solution
CREATE TRIGGER dbo.trg_NullableDateNulled_YourTable ON dbo.YourTable
AFTER UPDATE AS
BEGIN
IF EXISTS (SELECT 1
FROM inserted i
JOIN deleted d ON i.ID = d.ID
WHERE d.NullableDate IS NOT NULL
AND i.NullableDate IS NULL)
--Use an Error number relevant for your environment
THROW 78921,
N'A row where the column ''NullableDate'' has been set to NULL has been detected in the trigger ''trg_NullableDateNulled_YourTable''. Cannot update column ''NullableDate'' to be NULL when it previously had a non-NULL value in the object ''dbo.YourTable''.',
16;
END;
GO
然后,您可以使用以下工具进行测试(并清理(:
INSERT INTO dbo.YourTable (SomeColumn, NullableDate)
VALUES('asda',NULL),
('wera',GETDATE());
GO
--Following fails
UPDATE dbo.YourTable
SET NullableDate = NULL
WHERE SomeColumn = 'wera';
GO
--Following works
UPDATE dbo.YourTable
SET NullableDate = GETDATE()
WHERE SomeColumn = 'asda';
GO
--Following works
UPDATE dbo.YourTable
SET NullableDate = '20220317'
WHERE SomeColumn = 'wera';
GO
--Following fails (as now not NULL
UPDATE dbo.YourTable
SET NullableDate = NULL
WHERE SomeColumn = 'asda';
GO
SELECT *
FROM dbo.YourTable;
GO
DROP TABLE dbo.YourTable;
db<gt;小提琴
从@Larnu的答案更改下面的部分
IF EXISTS (SELECT 1 FROM inserted i
JOIN deleted d ON i.ID = d.ID
WHERE d.NullableDate IS NOT NULL
AND i.NullableDate IS NULL)
至以下
IF EXISTS (SELECT 1 FROM deleted d WHERE d.NullableDate IS NOT NULL)
以获得您想要的确切行为。
dbfiddle