[英]Problem with trigger for avoiding insert (Oracle SQL)
I'm trying to make a trigger to avoid inserting data in the table for this reason: If a patient is dead he can't make a visit.由于这个原因,我正在尝试制作一个触发器以避免在表中插入数据:如果患者已经死亡,他将无法访问。 I made a function that return a 1 if the patient is dead and I call it on the trigger.
我做了一个函数,如果病人死了,它会返回一个 1,我在触发器上调用它。 That's the code:
那是代码:
CREATE OR REPLACE FUNCTION check_d (pd INTEGER)
RETURN INTEGER
IS
d Patient.d_date%TYPE;
BEGIN
SELECT P.d_Date INTO d
FROM Patient P
WHERE P.idP=pd;
IF d <> NULL THEN
RETURN 1;
ELSE
RETURN 0;
END IF;
END;
CREATE OR REPLACE TRIGGER bad_insert
BEFORE INSERT ON Visit
FOR EACH ROW
DECLARE
idd INTEGER;
dp Visit.id_PV%TYPE;
BEGIN
SELECT V.id_PV INTO dp
FROM Visit V
WHERE id_PV=:NEW.id_PV;
idd := check_d(dp);
IF idd = 1 THEN
RAISE_APPLICATION_ERROR(-20014,'Error. Patient Deceased.');
END IF;
END;
/
The function should be ok, the problem is in thet trigger.功能应该没问题,问题出在trigger上。 Visit.id_PV is a Foreign Key to Patient.idP(PRIMARY KEY) anyway.
无论如何,Visit.id_PV 是 Patient.idP(PRIMARY KEY) 的外键。 How should I modify the code?
我应该如何修改代码? Thanks.
谢谢。
Your function is not correct你的功能不正确
d <> NULL
Will always return UNKNOWN, instead you have to check for nulls like:将始终返回 UNKNOWN,而您必须检查空值,例如:
d is not null
Once you've fixed that, you still have to work around the mutating table error you'd receive when you try an insert statement (did you not receive this when you tried it?).一旦你解决了这个问题,你仍然需要解决你在尝试插入语句时收到的变异表错误(你在尝试时没有收到这个错误吗?)。 You are referencing the same table you are inserting into within your trigger.
您正在引用您在触发器中插入的同一个表。 You can't do that.
你不能那样做。 Instead you should reference the column you want using :new.id_PV .
相反,您应该使用 :new.id_PV 引用您想要的列。
I think the problem is located here :我认为问题出在这里:
IF d <> NULL THEN
Change it to :将其更改为:
IF d IS NOT NULL THEN
In the current case, you'll get no_data_found
exception because of the query within the trigger.在当前情况下,由于触发器中的查询,您将获得
no_data_found
异常。 Moreover, you do not need to return the value for id_PV
column that you already have as :NEW.id_PV
, and such attempt mostly end with mutating trigger
error.此外,您不需要返回您已经拥有的
id_PV
列的值:NEW.id_PV
,并且这种尝试大多以mutating trigger
错误结束。 So , rearrange your trigger as因此,将触发器重新排列为
CREATE OR REPLACE TRIGGER bad_insert
BEFORE INSERT ON Visit
FOR EACH ROW
BEGIN
IF check_d(:NEW.id_PV) = 1 THEN
RAISE_APPLICATION_ERROR(-20014, 'Error. Patient Deceased.');
END IF;
END;
/
while getting rid of redundant local variables.同时摆脱多余的局部变量。
The function might also be made brief such as该功能也可以简短,例如
CREATE OR REPLACE FUNCTION check_d (pd Visit.id_PV%type) RETURN INT IS
val INT;
BEGIN
SELECT NVL(SUM(NVL2(P.d_Date,1,0)),0)
INTO val
FROM Patient P
WHERE P.idP=pd;
RETURN val;
END;
/
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.