以下触发器是停止双重预订房间并为预约提供替代房间。我在试图展示房间时遇到了问题。你能告诉我哪里出错了吗?
CREATE OR REPLACE TRIGGER CHECK_APPOINTMENT
BEFORE INSERT OR UPDATE OF APP_DATE,C_NO,
RM_NO,APP_TIME ON APPOINTMENT
FOR EACH ROW
DECLARE
CURSOR C_APP
IS
SELECT APP_DATE,C_NO,APP_TIME,RM_NO
FROM APPOINTMENT;
V_APP_DATE APPOINTMENT.APP_DATE%TYPE;
V_APP_TIME APPOINTMENT.APP_TIME%TYPE;
V_C_NO APPOINTMENT.C_NO%TYPE;
V_RM_NO APPOINTMENT.RM_NO%TYPE;
I_RM_NO APPOINTMENT.RM_NO%TYPE;
RM_BKED_ERROR EXCEPTION;
BEGIN
OPEN C_APP;
FETCH C_APP INTO V_APP_DATE,V_C_NO,V_APP_TIME,V_RM_NO;
IF :NEW.C_NO=V_C_NO
AND:NEW.RM_NO=V_RM_NO
AND:NEW.APP_DATE=V_APP_DATE
AND:NEW.APP_TIME=V_APP_TIME
THEN
RAISE RM_BKED_ERROR;
END IF;
SELECT R.RM_NO
INTO I_RM_NO
FROM ROOM R,BRANCH B
WHERE R.RM_NO <> :NEW.RM_NO
AND B.BRN_NO = :NEW.BRN_NO
AND B.BRN_NO=R.BRN_NO
GROUP BY R.RM_NO;
EXCEPTION
WHEN RM_BKED_ERROR THEN
Raise_Application_error (-20000, 'ROOM ALREADY BOOKED FOR AN APPOINTMENT.THE FOLLOWING ROOMS ARE AVAILABLE '||I_RM_NO);
CLOSE C_APP;
END;
/
答案 0 :(得分:4)
这看起来不是一种正确的方法,因为强制执行约束的触发器臭名昭着。
我会采用以下方法之一:
将约会预订代码封装在一个程序中,该程序首先获取任何表中的房间记录的独占锁定。然后它可以检查约会表中的重叠记录,并插入并提交所需的时间是免费的。返回一个代码,表明预订成功或不成功,如果不成功,也可能是其他可用房间的列表(并提交或回滚以释放房间桌锁)。由于房间不可用不是意外情况,我不会为此使用异常处理。
创建一个单独的表,每个房间有一行-minimum_booking_period(例如15分钟),房间和区间标识符上有唯一的密钥。使用该密钥违规通知预订不成功,但与第一种方法类似,不要将异常传回给应用程序。