【问题标题】:Triggers working correctly, but raise application error causing some errors with insert statements触发器正常工作,但引发应用程序错误,导致插入语句出现一些错误
【发布时间】:2021-03-21 09:48:13
【问题描述】:

我的代码如下所示。一切正常,但是当我的插入语句违反触发器时,它会因为我的 raise_application_error 而引发错误。

--Drop tables in case they were created previously
DROP TABLE enrollment Purge;
DROP TABLE offering Purge;
DROP TABLE faculty Purge;
DROP TABLE course Purge;
DROP TABLE student Purge;

--Create student table
CREATE TABLE student(StdID number(3) constraint student_StdID_PK primary key,
    StdFN varchar2(10),
    StdLN varchar2(15),
    StdCity varchar2(15),
    StdState char(2),
    StdZip number(5),
    StdMajor varchar2(4),
    StdClass char(2),
    StdGPA number(2,1),
        StdBalance NUMBER (12,2));

--create a table for courses and their descriptions
CREATE TABLE course(CourseNo varchar2(8) constraint course_courseNo_PK primary key,
    CrsDesc varchar2(40),
    CrsCredits number(1));

--create faculty table
CREATE TABLE Faculty(FacID number(4) constraint faculty_FacID_PK primary key,
    FacFN varchar2(10),
    FacLN varchar2(15),
    FacDept varchar2(4),
    FacRank varchar2(4),
    FacHireDate date,
    FacSalary number(6),
    FacSupervisor number(4));

--create table for offered courses
CREATE TABLE Offering(OfferNo number(4) constraint offering_OfferNo_PK primary key, 
    CourseNo varchar(8)constraint offering_crs_no references course(courseno), 
    OffTerm varchar2(6),
    OffYear number(4),
    OffLoca varchar(6),
    OffTime varchar(8),
    OffDay varchar(5),
    FacSSN number(4)constraint offering_fac_FK references faculty(facID));

--create table for student enrollment
CREATE TABLE enrollment(StdID number(3),
    OfferNo number(4),
    EnrGrade char(2),
    constraint enrollment_PK primary key (StdID,OfferNo),
    constraint enrollment_std_ID foreign key(StdID) references student(stdID),
    constraint enrollment_class_ID foreign key(offerno) references offering(offerno));
    
CREATE OR REPLACE TRIGGER UNPAID_BALANCE
BEFORE INSERT ON STUDENT
FOR EACH ROW
DECLARE
BAL NUMBER;
BEGIN
BAL := :NEW.STDBALANCE;
IF BAL > 500
THEN
RAISE_APPLICATION_ERROR(-20001, 'Your balance is too high to register. Please pay to continue.');
END IF;
END;
/
    
CREATE OR REPLACE TRIGGER ENROLL_MAX
BEFORE INSERT ON ENROLLMENT
FOR EACH ROW
DECLARE
NOFSTUDENTS BINARY_INTEGER;
BEGIN
SELECT COUNT(*) INTO NOFSTUDENTS
FROM ENROLLMENT
WHERE OFFERNO = :NEW.OFFERNO AND ENRGRADE IS NULL;
DBMS_OUTPUT.PUT_LINE(NOFSTUDENTS);
IF (NOFSTUDENTS + 1) > 2
THEN
RAISE_APPLICATION_ERROR(-20003, 'EXCEED MAX NO OF STUDENTS ALLOWED');
END IF;
END;
/

--populate student table
INSERT INTO student values(101,'Joe','Smith','Eau Clare','WI',18121,'IS','FR',3.8,225.25);
INSERT INTO student values(102, 'Rob','King', 'Melrose', 'MN', 56352, 'IS','JR',3.2,120.98);
INSERT INTO student values(103, 'Dan','Robinson', 'Sartell', 'MN', 98042, 'IS','JR',3.6, 36);
INSERT INTO student values(104,'Sue','Williams','St.Cloud','MN',56301,'ACCT','SR',3.2,2386.55);
INSERT INTO student values(105,'Don','Robinson','St.Paul','MN',55103,'MKTG','SR',3.4, 306);

--populate course table
INSERT INTO Course values('CSCI 200','Elements of Computing',3);
INSERT INTO Course values('IS 250','Application of Program Dev. I',3); 
INSERT INTO Course values('IS 251','Application of Program Dev. II',3);
INSERT INTO Course values('IS 454', 'Data Mining for Decision Support',3);
INSERT INTO Course values('IS 356','Systems Analysis and Design I',3);
INSERT INTO Course values('IS 460', 'Project Management',3);
INSERT INTO Course Values('ACCT 291','Accounting Principles II',3);
INSERT INTO Course values('IS 443','Database Design',3);

--populate faculty table
INSERT INTO faculty values(9001,'Leonard','Vince','IS','ASST','12-Apr-1997',67000,9003);
INSERT INTO faculty values(9002,'Victor','Strong','CSCI','ASSO','8-Aug-1999',70000,9003);
INSERT INTO faculty values(9003,'Nicki','Colan','IS','PROF','20-Aug-1981',75000,9010);
INSERT INTO faculty values(9004,'Fred','Wells','ACCT','ASST','28-Aug-1996',60000,9010);
INSERT INTO faculty values(9010,'Chris','Macon','ACCT','ASST','4-Aug-1980',75000,Null);

--populate offering table
INSERT INTO offering values(2201,'CSCI 200','Spring',2017,'ECC135','10:30AM','MWF',9002);
INSERT INTO offering values(2202,'CSCI 200','Spring',2017,'ECC135','8:00AM','MWF',9002);
INSERT INTO offering values(1102,'ACCT 291','Spring',2017,'CH 14A','2:00AM','MWF',9004);
INSERT INTO offering values(2203,'IS 356','Fall',2017,'CH494','3:30AM','TTH',9001);
INSERT INTO offering values(2204,'IS 251','Fall',2017,'CH494','12:30AM','TTH',9003);
INSERT INTO offering values(1101,'ACCT 291','Fall',2017,'CH350','12:30AM','TTH',9010);
INSERT INTO offering values(2205,'IS 443','Fall',2017,'CH494','9:30AM','MWF',9003);

--populate enrollment table
INSERT INTO enrollment values(101,2201,'A');
INSERT INTO enrollment values(102,2202,'B');
INSERT INTO enrollment values(102,2203,null);
INSERT INTO enrollment values(103,2203,null);
INSERT INTO enrollment values(103,2201,'C');
INSERT INTO enrollment values(103,1101,null);
INSERT INTO enrollment values(104,2202,'A');
INSERT INTO enrollment values(101,2203,null);
INSERT INTO enrollment values(101,1101,null);
INSERT INTO enrollment values(101,2205,null);
INSERT INTO enrollment values(102,2205,null);
INSERT INTO enrollment values(104,2205,null);

有没有一种方法可以使脚本输出部分看起来更清晰/更好,因为一个特定的情况是由于引发应用程序错误而弹出的错误消息。

从第 129 行开始的错误命令 -
INSERT INTO 注册值(104,2202,'A')
错误报告 -
ORA-02291: 违反完整性约束 (ADMIN_BF.ENROLLMENT_STD_ID) - 未找到父键

【问题讨论】:

    标签: sql database oracle triggers sql-insert


    【解决方案1】:

    您面临的错误很清楚。表中没有学生104,因此无法在enrollment 中创建依赖记录。此错误与您的触发器无关,而是与您的数据有关。

    现在让我们看看该特定用户的 insert 语句:

    INSERT INTO student values(104,'Sue','Williams','St.Cloud','MN',56301,'ACCT','SR',3.2,2386.55);
    

    您正在尝试输入2386.55 的余额。但是您的触发器UNPAID_BALANCE 阻止了高于500 的余额,因此insert 引发应用程序错误“您的余额太高无法注册”,这是问题的根本原因。您需要修复该插入。

    旁注:在最后一系列插入enrollments 中潜伏着另一个问题。触发器ENROLL_MAX 每个OFFERNO 只允许两个学生,但您正试图分配三个学生提供2203,以及三个学生提供2205。这将引发应用程序错误“EXCEED MAX NO OF STUDENTS ALLOWED”。

    【讨论】:

    • 我是否必须将触发器更改为在此之后而不是之前工作?我想要这些触发器的设置方式。
    • 我有两个业务规则(触发条件)一个是不允许学生余额在$500或以上,另一个是如果班级超过一定金额则不允许学生注册上课(2)。所以这两个触发器都可以正常工作,但是有没有办法在不引发这些错误的情况下显示其正常工作?
    • @Boooo402:问题不在于您的触发代码 - 那些按照他们的意图行事。问题在于您的数据,这违反了业务规则。改为修复您的数据。
    猜你喜欢
    • 2015-04-26
    • 2021-12-05
    • 2019-09-15
    • 1970-01-01
    • 1970-01-01
    • 2022-12-05
    • 2021-02-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多