【发布时间】:2015-04-10 15:14:48
【问题描述】:
我创建了触发器 A1,以便某个类型的文章(即“Bert”)不能多次添加,并且库存中只能有 1 个。 但是,尽管我创建了触发器,但我仍然可以添加类型为“Bert”的文章。不知何故,计数返回“0”,但是当我运行相同的 sql 语句时,它返回正确的数字。如果我放下触发器并重新添加它,它也会开始正确计数。有什么想法可能出了什么问题?
TRIGGER A1 BEFORE INSERT ON mytable
FOR EACH ROW
DECLARE
l_count NUMBER;
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
SELECT COUNT(*) INTO l_count FROM mytable WHERE article = :new.article;
dbms_output.put_line('Count: ' || l_count);
IF l_count >0 THEN
IF(:new.TYPEB = 'Bert') THEN
dbms_output.put_line('article already exists!');
ROLLBACK;
END IF;
ELSIF (:new.TYPEB = 'Bert' AND :new.stock_count>1) THEN
dbms_output.put_line('stock cannot have more than 1 of this article with type Bert');
ROLLBACK;
END IF;
END;
这是我使用的插入语句:
INSERT INTO mytable VALUES('Chip',1,9,1,'Bert');
【问题讨论】:
-
你为什么不为此使用唯一约束?
-
这种样式触发器不能工作。即使触发器是固定的,同时添加一条记录的两个事务也看不到对方,因为隔离,会允许添加。
-
可能你没有提交以前的插入,这对自主事务很重要。
-
并且在触发器中使用自治事务可能会产生无法预料的后果。此功能应谨慎使用,主要用于日志记录表。
-
Count(*) 按预期工作,但自治事务中的 ROLLBACK 仅回滚该自治事务,并且对导致触发器触发的语句没有影响。最好改用 raise_application_error。顺便说一句,即使来自同一个会话,自主事务也看不到未提交的数据!删除并重新创建触发器会隐式提交您的事务。
标签: sql oracle plsql triggers count