Reputation: 27
I am working within a hotel database. I am attempting to create a trigger that will change the availability status of a room before any new reservations are made based on if the current date falls between the check_in and check_out values of a room.
I have 2 errors from my compiler log:
SQL Statement Ignored on 'for each row'
and
ora00904: "status_in":invalid identifier
I would appreciate any assistance.
Tables:
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)
);
Trigger:
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;
Upvotes: 0
Views: 88
Reputation: 9150
The update
statement tries to update column status_in
of room
:
update room
set status_in = 'F'
but room
does not have that column. It has a status
column.
I'm also not sure what your intentions were regarding retrieving the old room status. Were you planning on using that to check something? If not, was your trigger just going to do something like this:
update room
set status = (sysdate between :old.check_in and :old.check_out)
where room_id = :old.room_id
;
If so, then you might also question whether you really want a status
column on the room
table at all. status
is actually a derived column. Setting the status
rather than computing it will leave you with the danger of an inconsistency. Instead, you could do something along these lines:
create table room(
room_id number(3) constraint room_pk primary key,
room_type varchar2(15) constraint room_fk references roomType
);
The querying:
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
;
Upvotes: 1