我想要防止三件事
1.如果现有日期早于2022-01-01,则禁止更新记录
1.如果新日期早于2022-01-01,则禁止更新记录
1.如果日期早于2022-01-01,则禁止插入。
基本上,如果日期早于2022-01-01,则不应允许插入或更新记录。
我试着用带有光标的触发器。我必须使用游标,因为它应该对批处理起作用。
CREATE TRIGGER TriggerDate
ON tb
AFTER INSERT,UPDATE
AS
BEGIN
DECLARE @IVDate Date;
DECLARE my_Cursor CURSOR FOR
SELECT InvoiceDate
FROM INSERTED;
OPEN my_Cursor;
FETCH NEXT FROM my_Cursor INTO @IVDate;
WHILE @@FETCH_STATUS = 0
BEGIN
FETCH NEXT FROM my_Cursor INTO @IVDate;
IF @IVDate < '2022-01-01'
ROLLBACK TRANSACTION
END
CLOSE my_Cursor;
DEALLOCATE my_Cursor;
END
但问题出现在INSERT语句的顺序上。
例如,以下语句运行良好。
insert into tb values (1, '2022-05-02','A');
insert into tb values (2, '2021-08-06','B');
但以下方法不起作用:
insert into tb values (2, '2021-08-06','B');
insert into tb values (1, '2022-05-02','A'); -- This record is correct but still it won't insert
具有WHERE条件和OR的UPDATE语句也会发生同样的情况
为了快速理解,请参考此dbfiddle
2条答案
按热度按时间doinxwow1#
请勿在
TRIGGER
中使用CURSOR
。触发器应该对调用语句有尽可能小的影响,而CURSOR
是您可以拥有的最影响的东西之一。这里您需要做的就是使用
EXISTS
来检查是否存在您不想要的行,而THROW
则是错误的。不要在TRIGGER
中使用ROLLBACK
,因为这会给最终用户带来有意义的错误;让外部查询处理事务的回滚:db<>fiddle
qf9go6mv2#
如果要从实际插入中排除插入,则可以在
INSTEAD OF INSERT
触发器中执行此操作InvoiceNo|InvoiceDate|CustomerName
-|-|
3|2021-08-06|B
4|2022-05-02|A
InvoiceNo|InvoiceDate|CustomerName
-|-|
3|2021-08-06|B
4|2022-05-02|A
InvoiceNo|InvoiceDate|CustomerName
-|-|
2|2022-05-02|A
fiddle