我必须在插入或更新某个关系之前检查关系A中的特定行属性是否等于或大于关系B中的相应行属性。我写了一个触发器:
尝试:
CREATE TRIGGER CandyCons AFTER INSERT, UPDATE ON Rel_A
AS
IF EXISTS (
SELECT * FROM Rel_A A, Rel_B B WHERE A.ID = B.ID AND A.candy > B.too_much
)
BEGIN
RAISERROR ('Stop eating!', 16, 1);
ROLLBACK TRANSACTION;
RETURN;
END;
我无法执行此操作。当我运行它时,我开始获得如下行号:
query
12
13
14
15
......... and so on
我该怎么办?
答案 0 :(得分:2)
在END;
之后的行上,输入一个斜杠(/
)告诉SQLPlus执行当前命令缓冲区。
另见When do I need to use a semicolon vs a slash in Oracle SQL?
(您的代码可能存在其他问题,其他答案可能会解决这些问题。但我相信这是您实际告诉SQLPlus编译和创建触发器的直接问题。)
答案 1 :(得分:1)
这可以使用行级TRIGGER
来完成,如下例所示。
首先创建表格:
CREATE TABLE REL_B(ID NUMBER NOT NULL PRIMARY KEY, TOO_MUCH NUMBER);
CREATE TABLE REL_A(ID NUMBER NOT NULL REFERENCES REL_B(ID), CANDY NUMBER);
然后添加一些测试数据:
INSERT INTO REL_B VALUES (1,10);
INSERT INTO REL_B VALUES (2,20);
COMMIT;
然后创建你的TRIGGER:
CREATE OR REPLACE TRIGGER CANDYCONS
AFTER INSERT OR UPDATE ON REL_A
FOR EACH ROW
DECLARE
V_COUNT_TOO_MUCH_CANDY NUMBER := 0;
BEGIN
SELECT COUNT(*) INTO V_COUNT_TOO_MUCH_CANDY
FROM REL_B
WHERE REL_B.ID = :NEW.ID
AND :NEW.CANDY > REL_B.TOO_MUCH;
IF (V_COUNT_TOO_MUCH_CANDY > 0)
THEN
RAISE_APPLICATION_ERROR(-20144,'Stop eating!');
END IF;
END;
/
然后测试:
没关系:
INSERT INTO REL_A VALUES (1,9);
INSERT INTO REL_A VALUES (1,10);
但这被阻止了:
INSERT INTO REL_A VALUES (1,11);
Error starting at line : 1 in command -
INSERT INTO REL_A VALUES (1,11)
Error report -
ORA-20144: Stop eating!
答案 2 :(得分:0)
我相信你打算这样:
Meteor.userId()
等待。 Oracle不支持CREATE TRIGGER CandyCons ON Rel_A
BEFORE INSERT, UPDATE
AS
IF EXISTS (SELECT 1 FROM Rel_B B WHERE :NEW.ID = B.ID AND :NEW.candy > B.too_much
)
BEGIN
RAISERROR ('Stop eating!', 16, 1);
ROLLBACK TRANSACTION;
RETURN;
END;
。它需要if exists
。所以:
then