2017-04-14 23 views
0

這是用於學校projet。PL SQL觸發倍數條件

我得到了一張表外科醫生與以下數據:idSurgeon,idType,idRoom,surgeryDate,BeginTime,EndTime。 (BeginTime和EndTime是手術小時的整數)。我嘗試創建一個觸發器,可以防止在同一房間同時進行兩次手術。

CREATE TRIGGER I_PreventSurgery 
BEFORE INSERT ON SURGEON 
FOR EACH ROW 
WHEN ((old.surgeryDate = new.surgeryDate) and (old.idRoom = 
new.idRoom)); 
BEGIN 
IF (((:new.BeginTime >= old.BeginTime) and (:new.BeginTime >= 
:old.EndTime)) and ((:new.EndTime <= old.EndTime) and (:EndTime >= 
:old.BeginTime))); 
THEN 
raise_application_error(-20100, '2 surgeries at the same times'); 
END; 
/

該觸發器不起作用:我收到了一個編譯錯誤。即使我嘗試輸入顯示錯誤,但我沒有明白。

我的錯誤是什麼?如何糾正條件?

提前感謝您的幫助

+1

創建表

CREATE TABLE SURGEON ( IDSURGEON NUMBER, IDTYPE NUMBER, IDROOM VARCHAR2(4), SURGERYDATE DATE, BEGINTIME NUMBER, ENDTIME NUMBER ); 

值您忘記 – GurV

+0

你在你的WHEN子句的結尾有一個多餘的分號來問一個問題。另外,我不認爲這個條款對你想要做的事情是必要的。 –

+0

我想檢查在同一日期,同一房間和同一時間沒有手術。我在when子句的末尾刪除了分號,並且仍然存在編譯錯誤。 –

回答

2

在你的扳機,你必須做一個select看起來在SURGEON與新行重疊的其他行。比較:old:new只適用於updating,可能唯一的原因是確定是否有任何關鍵字段(房間,日期,時間)發生了變化;如果沒有,您可能想要跳過碰撞檢查。

+0

你能告訴我如何使我的觸發器工作,以防止插入? –

+0

@ Jean-FrançoisGirard看看Seyran的答案 –

0

嘗試刪除;這是在whenif結束條件和檢查。

1

(對不起,沒有得到很好的英文) 如果它是學校項目最簡單的方法是

CREATE OR REPLACE TRIGGER I_PreventSurgery 
BEFORE INSERT ON SURGEON 
FOR EACH ROW 
BEGIN 

    for R in (select * 
       from SURGEON T 
       where T.IDROOM = :new.idroom 
       and T.SURGERYDATE = :new.surgerydate 
       and :new.begintime <= T.endtime and :new.endtime >= T.begintime) 
    loop 
     raise_application_error(-20100, '2 surgeries at the same times'); 
    end loop; 

end; 

這一個示例展示瞭如何解決這個問題唯一索引檢查。 它不包括舊記錄的更新情況,僅涵蓋將新記錄添加到表中。

如果將運行的應用程序(這是不可能的, 但儘管如此)我會做到以下幾點,首先創建一個表

-- Create table 
create table SURGEONBYHOUR 
(
    uniqid VARCHAR2(19) not null 
); 

那麼唯一索引

-- Create/Recreate indexes 
create unique index I_SURGEONBYHOUR_UNIQID on SURGEONBYHOUR (UNIQID); 

觸發器將是這一個

CREATE OR REPLACE TRIGGER I_PreventSurgery 
BEFORE INSERT ON SURGEON 
FOR EACH ROW 
BEGIN 
    for li in :new.begintime .. :new.endtime 
    loop 
     insert into SURGEONBYHOUR 
     (UNIQID) 
     values 
     (to_char(:new.surgerydate, 'yyyymmdd') || 
      lpad(:new.idroom, 4, '0') || lpad(li, 2, '0')); 
    end loop; 
end; 

測試:SURGEON表 - 測試

insert into surgeon 
    (idsurgeon, idtype, idroom, surgerydate, begintime, endtime) 
values 
    (1, 1, 52, '01/01/17', 11, 13); 

insert into surgeon 
    (idsurgeon, idtype, idroom, surgerydate, begintime, endtime) 
values 
    (2, 1, 53, '01/01/17', 12, 15); 
insert into surgeon 
    (idsurgeon, idtype, idroom, surgerydate, begintime, endtime) 
values 
    (3, 2, 52, '01/01/17', 12, 14); 
+1

你可以縮短你的檢查時間並使其正確工作:而不是'(:new.begintime <= T.endtime和:new.begintime> = t.begintime或:new.endtime> = T.begintime和:new.endtime <= T.endtime))',只需寫入':new.begintime T.begintime'。您檢查無法檢測到例如:新= 01:00-05:00和T = 02:00-04:00 –

+0

@ammoQ你是對的,謝謝。 – Seyran