2017-05-06 46 views
0

我正在酒店数据库中工作。我试图创建一个触发器,根据当前日期是否在房间的check_in和check_out值之间进行任何新预留之前,更改房间的可用状态。尝试创建触发器时出错(忽略无效的标识符和sql)

我从我的编译器日志2个错误:

SQL Statement Ignored on 'for each row'

ora00904: "status_in":invalid identifier

我将不胜感激的任何援助。

表:

create table room(
    room_id number(3) constraint room_pk primary key, 
    room_type varchar2(15) constraint room_fk references roomType, 
    status char(1) 
); 

create table reservation(
    reservation_id number(6) constraint reservation_pk primary key, 
    check_in date, 
    check_out date, 
    room_id number(3), 
    guest_id varchar2(5), 
    foreign key (room_id) references room(room_id), 
    foreign key (guest_id) references guest(guest_id) 
); 

触发:

create or replace trigger room_status 
before insert on reservation 
for each row 
declare 
    status_in room.status%type; 
    error1 exception; 
begin 

    select status 
     into status_in 
     from room 
     where room_id = :old.room_id; 

    if sysdate between :old.check_in and :old.check_out then 
     update room 
     set status_in = 'F' 
     where room_id = :old.room_id; 
    else 
     update room 
     set status_in = 'T' 
     where room_id = :old.room_id; 
    end if; 

exception 
    when error1 then 
    raise_application_error(-20100,'Insert Cancelled'); 
end; 
+0

我必须说,我更喜欢具体的Y/N指标这些模糊状态列表。我猜'T'和'F'的意思是'TRUE'和'FALSE',但是'TRUE'是怎么样的状态?在我们处于这个状态时命名列'occupied_yn'(和'varchar2(1)not null',再加上一个只允许'Y'或'N'的检查约束)会使事情变得更加清晰。 –

回答

1

update语句试图更新列的roomstatus_in

update room 
    set status_in = 'F' 

room没有该列。它有一个status列。

我也不确定你的意图是检索旧房间的状态。你计划用它来检查某些东西吗?如果没有,是你的触发器只是打算做这样的事情:

update room 
    set status = (sysdate between :old.check_in and :old.check_out) 
    where room_id = :old.room_id 
; 

如果是这样,那么你也可能会怀疑你是否真的想在roomstatus列在所有。 status实际上是一个派生列。设置status而不是计算它会给你带来不一致的危险。相反,你可以做一些沿着这些路线:

create table room(
    room_id number(3) constraint room_pk primary key, 
    room_type varchar2(15) constraint room_fk references roomType 
); 

的查询:

SELECT r.room_id 
     ,r.room_type 
     ,SUM(CASE WHEN sysdate between :old.check_in and :old.check_out THEN 1 ELSE 0 END) AS status 
    FROM room r 
    JOIN reservation v ON (v.room_id = r.room_id) 
    GROUP BY r.room_id, r.room_type 
    ; 
+0

谢谢你的回应!触发器编译正常,但现在我得到错误:01403:找不到数据。我使用这个插入语句来检查:insert into reservation values(reservation_sequence.nextval,to_date('05 -03-2017','mm/dd/yyyy'),to_date('05 -07-2017','mm/dd/yyyy'),'107','G180') – kate8895

+0

这是'select ... into',会抛出'no data found'异常。那么有没有一个价值为'107'的房间?约束是否有效? (另外,插入时不要引用数字) – Glenn

+0

评论有点长,请参阅更新的答案。 – Glenn