PL / SQL触发器检查screening_start_hh24是否在plan_min_start_hh24和plan_max_start_hh24之间

时间:2017-09-07 14:45:45

标签: sql oracle plsql triggers

这些是我创建的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表中插入行之前触发。触发器应检查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:未找到数据。但是我希望错误消息显示为 ORA-20001:屏幕开始时间应该在计划的最小开始时间和计划的最长开始时间之间

我在触发器代码中哪里犯了错误?

如果提供了解决方案代码,那将非常有用。

1 个答案:

答案 0 :(得分:1)

这部分:

v_screening_start_hh24 := :new.screening_start_hh24;

错误并导致NO_DATA_FOUND,因为新行还没有!

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

if(strlen($string) >= 1 && empty(trim($string))) {