触发器不使用正确的if语句

时间:2015-03-18 18:51:07

标签: sql oracle triggers

好的,这可能是一个简单的修复,但我似乎无法找到问题。 我有一个像这样定义的表:

CREATE TABLE Prenotazione (
Mat_docente         char(10),
Nome_sede           varchar2(30),
Num_aula            varchar2(3),
Tipo_aula           varchar2(15),
Motivazione         varchar2(20)    NOT NULL,
Affluenza           NUMBER(3)       NOT NULL,
Data_ptz_aula       date            NOT NULL,
Inizio_ptz_aula     date,
Fine_ptz_aula       date,
--
CONSTRAINT fk_Prenotazione_docente  FOREIGN KEY (Mat_docente) REFERENCES Docente(Mat_docente) ON DELETE CASCADE,
CONSTRAINT fk_Prenotazione_aula     FOREIGN KEY (Nome_sede,Num_aula,Tipo_aula) REFERENCES Aula(Nome_sede,Num_aula,Tipo_aula) ON DELETE CASCADE,
CONSTRAINT pk_Prenotazione          PRIMARY KEY (Mat_docente,Inizio_ptz_aula,Fine_ptz_aula),
CHECK       (trunc(inizio_ptz_aula) = trunc(fine_ptz_aula)), -- data inizio = data fine // prenotazione giornaliera
CHECK       ( Inizio_ptz_aula < Fine_ptz_aula ),                -- ora inizio < ora fine   // coerenza temporale
CHECK       (Motivazione in ('Lezione','Seminario','Esercitaz','Esame','Assemblea','Altro'))

我指定一个触发器,特别是:

CREATE OR REPLACE TRIGGER Controllo_prenotazione
BEFORE INSERT OR UPDATE ON Prenotazione
FOR EACH ROW
DECLARE
EX_ONE EXCEPTION;
EX_TWO EXCEPTION;
BEGIN
IF trunc(:NEW.Inizio_ptz_aula) < trunc(next_day(sysdate,1))
THEN RAISE EX_ONE;
END IF;
IF to_number(to_char(sysdate,'d'),'9') > 5
THEN RAISE EX_TWO;
END IF;
EXCEPTION
WHEN EX_ONE THEN RAISE_APPLICATION_ERROR(-200011,'Non è possibile prenotare nella settimana corrente');
WHEN EX_TWO THEN RAISE_APPLICATION_ERROR(-200012,'Non è possibile prenotare nel weekend');
END;
/

现在,当我尝试插入一行时,让我们说:

    insert into prenotazione values ('1124000003',
'Centro Direzionale',
NULL,
'Aula',
'Lezione',
250,
sysdate,
to_date('28-03-2015 16:30','dd-mm-yyyy hh24:mi'), 
to_date('28-03-2015 18:30','dd-mm-yyyy hh24:mi'));

我收到此错误:

ERROR at line 1:
ORA-01846: not a valid day of the week
ORA-06512: at "ADMIN.CONTROLLO_PRENOTAZIONE", line 5
ORA-04088: error during execution of trigger 'ADMIN.CONTROLLO_PRENOTAZIONE'

提到了第一个IF条款。 发生了什么 ? 参数

trunc(next_day(sysdate,1))

按预期工作,正如我在检查双表后可以说的那样,插件在没有触发器的情况下工作,所以这不是与ddl相关的问题。

感谢您的时间和提前提供的任何帮助。

2 个答案:

答案 0 :(得分:2)

在次日声明中为MONDAY替换1可以解决问题

CREATE OR REPLACE TRIGGER Controllo_prenotazione
BEFORE INSERT OR UPDATE ON Prenotazione
FOR EACH ROW
DECLARE
EX_ONE EXCEPTION;
EX_TWO EXCEPTION;
BEGIN 

 IF trunc(:NEW.Inizio_ptz_aula) < trunc(next_day(sysdate,'MONDAY'))
 THEN RAISE EX_ONE;
 END IF;

  IF to_number(to_char(sysdate,'d'),'9') > 5
 THEN RAISE EX_TWO;
  END IF;
  EXCEPTION
 WHEN EX_ONE THEN RAISE_APPLICATION_ERROR(-200011,'Non e possibile   prenotare nella settimana corrente');
  WHEN EX_TWO THEN RAISE_APPLICATION_ERROR(-200012,'Non e possibile prenotare nel weekend');
  END;
  /

这是一种非常奇怪的行为,因为它作为一个select语句,但不在触发器

  select next_day(sysdate,1) from dual;

答案 1 :(得分:1)

NEXT_DAY()确实与SQL中的数字一起使用,但它不适用于PL / SQL中的数字:

SELECT NEXT_DAY(SYSDATE, 2) FROM dual;

返回:

  

3/23/2015 3:16:11 PM

然而,

BEGIN
    DBMS_OUTPUT.PUT_LINE('Monday: ' || NEXT_DAY(SYSDATE, 2) );
END;
/

引发错误:

  

[错误]脚本行:1-4 -------------------------- ORA-01846:不是一周中的有效日期< / p>

因此,在您的存储过程中,请使用字符串作为NEXT_DAY()的第二个参数:

IF trunc(:NEW.Inizio_ptz_aula) < trunc(next_day(sysdate, 'MONDAY'))