用于检查外键在PLSQL中不工作的触发器

用于检查外键在PLSQL中不工作的触发器,sql,database,oracle,plsql,Sql,Database,Oracle,Plsql,下面是我正在使用的2个表 create table EMPLOYEE ( Eid number(5) primary key, Ename char(30), Designation char(30)); create table Attendance ( Eid number(5) references EMPLOYEE(Ei

下面是我正在使用的2个

create table EMPLOYEE (
                    Eid number(5) primary key,
                    Ename char(30),
                    Designation char(30));

create table Attendance (
                        Eid number(5) references EMPLOYEE(Eid),
                        tdate date,
                        attendance char(2) check(attendance in('P','A')));
create or replace TRIGGER to_take_attendance
before insert or update of eid on ATTENDANCE
for each row
declare
    CURSOR c(n number) is select * from EMPLOYEE where eid = :new.eid;
    e c%rowtype;
    invalid_id EXCEPTION;
begin
open c(:new.eid);
    fetch c into e;
    if c%NOTFOUND then
        raise invalid_id;
    else
        NULL;
    end if;

EXCEPTION   
when invalid_id then
    close c;
    raise_application_error(-20001,'Invalid ID');

close c;
end;
这是我用来考勤的
程序

create or replace PROCEDURE take_attendance(
                                            id IN number,
                                            attendance IN char) IS
begin 
    insert into ATTENDANCE Values(id, sysdate, attendance);
end;
这是我正在使用的
触发器

create table EMPLOYEE (
                    Eid number(5) primary key,
                    Ename char(30),
                    Designation char(30));

create table Attendance (
                        Eid number(5) references EMPLOYEE(Eid),
                        tdate date,
                        attendance char(2) check(attendance in('P','A')));
create or replace TRIGGER to_take_attendance
before insert or update of eid on ATTENDANCE
for each row
declare
    CURSOR c(n number) is select * from EMPLOYEE where eid = :new.eid;
    e c%rowtype;
    invalid_id EXCEPTION;
begin
open c(:new.eid);
    fetch c into e;
    if c%NOTFOUND then
        raise invalid_id;
    else
        NULL;
    end if;

EXCEPTION   
when invalid_id then
    close c;
    raise_application_error(-20001,'Invalid ID');

close c;
end;
下面是我得到的
错误

begin
*
ERROR at line 1: 
ORA-20001: Invalid ID 
ORA-06512: at "101503028.TO_TAKE_ATTENDANCE", line 17 
ORA-04088: error during execution of trigger '101503028.TO_TAKE_ATTENDANCE' 
ORA-06512: at "101503028.TAKE_ATTENDANCE", line 5 
ORA-06512: at line 2
我不知道为什么我会犯这些错误。我是PL/SQL新手,我的问题是我可能会很愚蠢

谢谢


编辑-删除了异常中的其他项。

由于触发器按预期工作,因此出现错误。
您正在尝试向考勤中插入员工中不存在的ID

代码中定义的异常:
引发应用程序错误(-20001,“无效ID”)

收到错误:

ORA-20001无效ID

不清楚触发器的用途。数据库系统已经强制执行外键值的有效性,而不需要您定义触发器。我应该为同样的目的实现触发器。@lord_ozb作为旁白,摆脱when others子句-您当前正在将每个错误屏蔽为无效id。当有人向您走来并说“当我为存在的id插入一行时,我得到的是‘无效id’”,这对您没有帮助。然而,正如Damien所说,外键已经强制执行员工eid已经存在的规则。你为什么要执行触发器?这是一个家庭作业问题,还是某种业务要求?如果您试图很好地处理错误,那么最好在调用insert的代码中进行处理。@Boneist谢谢。我已经放弃了这个想法或触发器,现在使用异常处理。@lord_ozb这是最好的处理方法,IMHO。只是不要假设每个错误都是无效的id;通过不必要地掩盖错误,给自己一些调试问题的希望吧!稍后你会感谢你自己,我保证*{:-)但这怎么办?
ORA-04088:触发器执行过程中的错误'101503028。要参加会议
@lord\u ozb-忽略它。只是一系列例外。这只是触发器失败的一般信息。