【问题标题】:PL/SQL trigger to check if if screening_start_hh24 is between plan_min_start_hh24 and plan_max_start_hh24PL/SQL 触发器检查是否screening_start_hh24 在plan_min_start_hh24 和plan_max_start_hh24 之间
【发布时间】:2017-09-07 14:45:45
【问题描述】:

这些是我创建并插入了它们的值的 2 个表和 2 个序列:

CREATE TABLE Screening_Plan
  (
   plan_id NUMBER(4) PRIMARY KEY,
   CONSTRAINT check_plan_id CHECK(plan_id > 0),
   movie_id NUMBER(4) NOT NULL,
   plan_start_date DATE DEFAULT NEXT_DAY(SYSDATE,'MON') NOT NULL,
   plan_end_date DATE DEFAULT NEXT_DAY(SYSDATE + 6,'MON') NOT NULL,
   plan_min_start_hh24 NUMBER(2) DEFAULT 9 NOT NULL,
   CONSTRAINT check_plan_min_start_hh24 CHECK(plan_min_start_hh24 BETWEEN 9 AND 22),
   plan_max_start_hh24 NUMBER(2) DEFAULT 22 NOT NULL,
   CONSTRAINT check_plan_max_start_hh24 CHECK((plan_max_start_hh24 BETWEEN 9 AND 22) AND (plan_max_start_hh24 >=  plan_min_start_hh24)),
   plan_no_of_screenings NUMBER(2) NOT NULL,
   CONSTRAINT check_plan_no_of_screenings CHECK(plan_no_of_screenings >= 1),
   CONSTRAINT unique_movie_id_plan_start_date UNIQUE(movie_id,plan_start_date)
   );


   CREATE TABLE Screening
  (
   screening_id NUMBER(6) PRIMARY KEY,
   CONSTRAINT check_screening_id CHECK(screening_id > 0),
   plan_id NUMBER(4) NOT NULL,
   CONSTRAINT fk_plan_id FOREIGN KEY(plan_id) REFERENCES Screening_Plan(plan_id),
   theatre_id NUMBER(1) NOT NULL,
   screening_date DATE DEFAULT CURRENT_DATE NOT NULL,
   screening_start_hh24 NUMBER(2) NOT NULL,
   CONSTRAINT check_start_hh24 CHECK(screening_start_hh24 BETWEEN 9 AND 22),
   screening_start_mm60 NUMBER(2) NOT NULL,
   CONSTRAINT check_start_mm60 CHECK(screening_start_mm60 BETWEEN 0 AND 59),
   CONSTRAINT unique_theatre_id_screening_date_screening_start_hh24_screening_start_mm60 UNIQUE(theatre_id,screening_date,screening_start_hh24,screening_start_mm60)
  );

CREATE SEQUENCE screening_plan_seq 
START WITH 1 
INCREMENT BY 1 
NOCACHE NOCYCLE;

CREATE SEQUENCE screening_seq 
START WITH 1 
INCREMENT BY 1 
NOCACHE NOCYCLE;

INSERT INTO Screening_Plan (plan_id,movie_id,plan_start_date,plan_end_date,plan_min_start_hh24,plan_max_start_hh24,plan_no_of_screenings)
VALUES (screening_plan_seq.NEXTVAL,1,TO_DATE('11/9/2017','DD/MM/YYYY'),TO_DATE('08/10/2017','DD/MM/YYYY'),9,17,6);
INSERT INTO Screening_Plan (plan_id,movie_id,plan_start_date,plan_end_date,plan_min_start_hh24,plan_max_start_hh24,plan_no_of_screenings)
VALUES (screening_plan_seq.NEXTVAL,2,TO_DATE('11/9/2017','DD/MM/YYYY'),TO_DATE('08/10/2017','DD/MM/YYYY'),9,17,5);
INSERT INTO Screening_Plan (plan_id,movie_id,plan_start_date,plan_end_date,plan_min_start_hh24,plan_max_start_hh24,plan_no_of_screenings)
VALUES (screening_plan_seq.NEXTVAL,3,TO_DATE('11/9/2017','DD/MM/YYYY'),TO_DATE('08/10/2017','DD/MM/YYYY'),9,21,4);
INSERT INTO Screening_Plan (plan_id,movie_id,plan_start_date,plan_end_date,plan_min_start_hh24,plan_max_start_hh24,plan_no_of_screenings)
VALUES (screening_plan_seq.NEXTVAL,4,TO_DATE('11/9/2017','DD/MM/YYYY'),TO_DATE('08/10/2017','DD/MM/YYYY'),9,21,4);

INSERT INTO Screening (screening_id,plan_id,theatre_id,screening_date,screening_start_hh24,screening_start_mm60)
VALUES (screening_seq.NEXTVAL,1,3,TO_DATE('11/9/2017','DD/MM/YYYY'),9,0);
INSERT INTO Screening (screening_id,plan_id,theatre_id,screening_date,screening_start_hh24,screening_start_mm60)
VALUES (screening_seq.NEXTVAL,1,3,TO_DATE('11/9/2017','DD/MM/YYYY'),11,0);
INSERT INTO Screening (screening_id,plan_id,theatre_id,screening_date,screening_start_hh24,screening_start_mm60)
VALUES (screening_seq.NEXTVAL,1,3,TO_DATE('11/9/2017','DD/MM/YYYY'),13,0);
INSERT INTO Screening (screening_id,plan_id,theatre_id,screening_date,screening_start_hh24,screening_start_mm60)
VALUES (screening_seq.NEXTVAL,1,2,TO_DATE('11/9/2017','DD/MM/YYYY'),13,0);
INSERT INTO Screening (screening_id,plan_id,theatre_id,screening_date,screening_start_hh24,screening_start_mm60)
VALUES (screening_seq.NEXTVAL,1,3,TO_DATE('11/9/2017','DD/MM/YYYY'),15,0);
INSERT INTO Screening (screening_id,plan_id,theatre_id,screening_date,screening_start_hh24,screening_start_mm60)
VALUES (screening_seq.NEXTVAL,1,3,TO_DATE('11/9/2017','DD/MM/YYYY'),17,0);
INSERT INTO Screening (screening_id,plan_id,theatre_id,screening_date,screening_start_hh24,screening_start_mm60)
VALUES (screening_seq.NEXTVAL,2,1,TO_DATE('11/9/2017','DD/MM/YYYY'),9,0);
INSERT INTO Screening (screening_id,plan_id,theatre_id,screening_date,screening_start_hh24,screening_start_mm60)
VALUES (screening_seq.NEXTVAL,2,1,TO_DATE('11/9/2017','DD/MM/YYYY'),12,0);
INSERT INTO Screening (screening_id,plan_id,theatre_id,screening_date,screening_start_hh24,screening_start_mm60)
VALUES (screening_seq.NEXTVAL,2,1,TO_DATE('11/9/2017','DD/MM/YYYY'),15,0);
INSERT INTO Screening (screening_id,plan_id,theatre_id,screening_date,screening_start_hh24,screening_start_mm60)
VALUES (screening_seq.NEXTVAL,2,2,TO_DATE('11/9/2017','DD/MM/YYYY'),9,0);
INSERT INTO Screening (screening_id,plan_id,theatre_id,screening_date,screening_start_hh24,screening_start_mm60)
VALUES (screening_seq.NEXTVAL,2,2,TO_DATE('11/9/2017','DD/MM/YYYY'),15,0);
INSERT INTO Screening (screening_id,plan_id,theatre_id,screening_date,screening_start_hh24,screening_start_mm60)
VALUES (screening_seq.NEXTVAL,3,4,TO_DATE('11/9/2017','DD/MM/YYYY'),9,0);
INSERT INTO Screening (screening_id,plan_id,theatre_id,screening_date,screening_start_hh24,screening_start_mm60)
VALUES (screening_seq.NEXTVAL,3,4,TO_DATE('11/9/2017','DD/MM/YYYY'),12,0);
INSERT INTO Screening (screening_id,plan_id,theatre_id,screening_date,screening_start_hh24,screening_start_mm60)
VALUES (screening_seq.NEXTVAL,3,4,TO_DATE('11/9/2017','DD/MM/YYYY'),15,0);
INSERT INTO Screening (screening_id,plan_id,theatre_id,screening_date,screening_start_hh24,screening_start_mm60)
VALUES (screening_seq.NEXTVAL,3,4,TO_DATE('11/9/2017','DD/MM/YYYY'),18,0);
INSERT INTO Screening (screening_id,plan_id,theatre_id,screening_date,screening_start_hh24,screening_start_mm60)
VALUES (screening_seq.NEXTVAL,4,1,TO_DATE('11/9/2017','DD/MM/YYYY'),18,0);
INSERT INTO Screening (screening_id,plan_id,theatre_id,screening_date,screening_start_hh24,screening_start_mm60)
VALUES (screening_seq.NEXTVAL,4,2,TO_DATE('11/9/2017','DD/MM/YYYY'),18,0);
INSERT INTO Screening (screening_id,plan_id,theatre_id,screening_date,screening_start_hh24,screening_start_mm60)
VALUES (screening_seq.NEXTVAL,4,3,TO_DATE('11/9/2017','DD/MM/YYYY'),19,0);
INSERT INTO Screening (screening_id,plan_id,theatre_id,screening_date,screening_start_hh24,screening_start_mm60)
VALUES (screening_seq.NEXTVAL,4,4,TO_DATE('11/9/2017','DD/MM/YYYY'),21,0);

那么我有以下作业问题:

创建在筛选表中插入行之前触发的 TR_validate_screening_time 触发器。触发器应检查screening_start_hh24 是否在plan_min_start_hh24 和plan_max_start_hh24 之间。如果不是,触发器应该引发应用程序错误并带有有意义的消息。 [注:screening_start_hh24 在 Screening 表中,plan_min_start_hh24、plan_min_start_hh24 在 Screening_Plan 表中]

这是我的触发逻辑:

CREATE OR REPLACE TRIGGER TR_validate_screening_time 
BEFORE INSERT
ON Screening 
FOR 
EACH ROW
DECLARE 
v_screening_start_hh24 Screening.screening_start_hh24%TYPE;
v_plan_min_start_hh24 Screening_Plan.plan_min_start_hh24%TYPE;
v_plan_max_start_hh24 Screening_Plan.plan_max_start_hh24%TYPE;
BEGIN
SELECT screening_start_hh24 INTO v_screening_start_hh24 
FROM Screening 
WHERE screening_id = :NEW.screening_id;
SELECT plan_min_start_hh24,plan_max_start_hh24 INTO v_plan_min_start_hh24,v_plan_max_start_hh24
FROM Screening_Plan
WHERE plan_id = :NEW.plan_id;
IF (v_screening_start_hh24 < v_plan_min_start_hh24) OR (v_screening_start_hh24 > v_plan_max_start_hh24)
THEN
RAISE_APPLICATION_ERROR(-20001,'Screening start time should be between planned minimum start hour and planned maximum start hour');
END IF;
END;

触发器编译成功如下图:

Trigger TR_VALIDATE_SCREENING_TIME compiled

为了确保触发器成功运行,我尝试通过在screening_start_hh24 列输入无效值:

INSERT INTO Screening (screening_id,plan_id,theatre_id,screening_date,screening_start_hh24,screening_start_mm60)
VALUES (screening_seq.NEXTVAL,1,1,TO_DATE('12/9/2017','DD/MM/YYYY'),8,0);

然后我收到以下消息:

Error report -
ORA-01403: no data found
ORA-06512: at "SCM_JC450912.TR_VALIDATE_SCREENING_TIME", line 6
ORA-04088: error during execution of trigger 'SCM_JC450912.TR_VALIDATE_SCREENING_TIME'

问题是我收到的错误消息显示为 ORA-01403: no data found。但我希望将错误消息显示为 ORA-20001:筛选开始时间应介于计划的最小开始时间和计划的最大开始时间之间

我的触发代码哪里出错了?

如果提供解决方案代码将非常有帮助。

【问题讨论】:

    标签: sql oracle plsql triggers


    【解决方案1】:

    这部分:

    SELECT screening_start_hh24 INTO v_screening_start_hh24 
    FROM Screening 
    WHERE screening_id = :NEW.screening_id;
    

    是错误的,将导致 NO_DATA_FOUND 因为新行还不存在!

    幸运的是,您真正需要的是:

    v_screening_start_hh24 := :new.screening_start_hh24;
    

    【讨论】:

    • 现在它可以工作了......非常感谢您发现我的错误。
    猜你喜欢
    • 1970-01-01
    • 2015-08-24
    • 2012-03-09
    • 1970-01-01
    • 2013-03-25
    • 1970-01-01
    • 2013-07-07
    • 2014-01-07
    • 2011-09-05
    相关资源
    最近更新 更多