我正在尝试创建一个简单的触发器,它必须检查插入和更新时的给定值。我必须检查ID是否与NAVAZUJE_NA(外键引用ID)不同。这是代码:
CREATE OR REPLACE TRIGGER PREDMETY_INSERT_TRIGGER
BEFORE INSERT OR UPDATE ON PREDMETY
FOR EACH ROW
BEGIN
IF :NEW.ID = :NEW.NAVAZUJE_NA THEN --There is an error (PLS-00405)
RAISE_APPLICATION_ERROR(-20000, 'Predmet nemuze navazovat sam na sebe.', FALSE);
ELSIF :NEW.NAVAZUJE_NA > (SELECT MAX(ID) FROM PREDMETY) THEN
RAISE_APPLICATION_ERROR(-20001, 'Predmet nemuze navazovat na neexistujici predmet.', FALSE);
ELSIF :NEW.ID < 0 OR :NEW.NAVAZUJE_NA < 0 THEN
RAISE_APPLICATION_ERROR(-20002, 'Neplatny index predmetu nebo predmetu, na ktery ma dany predmet navazovat.', FALSE);
END IF;
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('[ERROR] '||sqlerrm);
END;
感谢任何解决方案。
答案 0 :(得分:1)
如果您有11g或12c,您可以编写复合触发器。它有一个在实际触发活动开始之前执行的部分。也就是说,您可以从该部分的表中读取,因为这是在表进入变异状态之前:
create or replace trigger Predmety_Ciu
For Insert Or Update On Predmety
Compound Trigger
MaxID int;
Before Statement Is Begin
-- Be prepared this might be the first record written to the table
select nvl( max( ID ), 0 ) into MaxID from Predmety;
End Before Statement;
Before Each Row Is Begin
IF :NEW.ID = :NEW.NAVAZUJE_NA THEN --There is an error (PLS-00405)
Raise_Application_Error(-20000, 'Predmet nemuze navazovat sam na sebe.', False);
Elsif :New.Navazuje_Na > Maxid Then
Raise_Application_Error(-20001, 'Predmet nemuze navazovat na neexistujici predmet. Další objekt ID: ' || to_char( Maxid ), False);
Elsif :New.Id < 0 Or :New.Navazuje_Na < 0 Then
Raise_Application_Error(-20002, 'Neplatny index predmetu nebo predmetu, na ktery ma dany predmet navazovat.', False);
End If;
End Before Each Row;
After Each Row Is Begin
-- Vložte nějaký kód, který chcete spustit po vložení řádku
If Inserting Then
Maxid := Maxid + 1;
end if;
End After Each Row;
After Statement Is Begin
Null; -- Vložte nejaký kód, který chcete spustit po zadání všech rádek.
End After Statement;
End Predmety_Ciu;
我删除了异常处理程序,因为我想要例外。
答案 1 :(得分:0)
当你将max id提取到变量并在if语句中使用变量时,它会起作用。
CREATE OR REPLACE TRIGGER PREDMETY_INSERT_TRIGGER
BEFORE INSERT OR UPDATE ON PREDMETY
FOR EACH ROW
declare
c number;
BEGIN
SELECT MAX(ID) into c FROM PREDMETY;
IF :NEW.ID = :NEW.NAVAZUJE_NA THEN --There is an error (PLS-00405)
RAISE_APPLICATION_ERROR(-20000, 'Predmet nemuze navazovat sam na sebe.', FALSE);
ELSIF :NEW.NAVAZUJE_NA > c THEN
RAISE_APPLICATION_ERROR(-20001, 'Predmet nemuze navazovat na neexistujici predmet.', FALSE);
ELSIF :NEW.ID < 0 OR :NEW.NAVAZUJE_NA < 0 THEN
RAISE_APPLICATION_ERROR(-20002, 'Neplatny index predmetu nebo predmetu, na ktery ma dany predmet navazovat.', FALSE);
END IF;
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('[ERROR] '||sqlerrm);
END;