2017-05-06 6 views
0

私はホテルのデータベース内で働いています。現在の日付が部屋のcheck_in値とcheck_out値の間にある場合に基づいて、新しい予約が行われる前に部屋の空き状況を変更するトリガーを作成しようとしています。トリガーを作成しようとするとエラーが発生します(無効なidentiferとsqlは無視されます)

SQL Statement Ignored on 'for each row'

ora00904: "status_in":invalid identifier

私はどのような援助をお願い申し上げ:

は、私は私のコンパイラログからの2個のエラーを持っています。

テーブル:

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 
; 

もしそうなら、あなたは本当にすべてでroomテーブルの上にstatus列をしたいかどうか、あなたはまた、問題がありますされていない場合、あなたのトリガはちょうどこのような何かをするつもりでした。 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:データが見つかりません。私はこの挿入ステートメントを使用してチェックしています:予約への挿入 値(予約_シーケンス_nextval、to_date('05 -03-2017 '、' mm/dd/yyyy ')、to_date('05 -07-2017'、 'mm/dd/yyyy ')、' 107 '、' G180 ') – kate8895

+0

'no data found'例外をスローするのは' select ... into'です。値107の部屋はありますか?制約はアクティブですか? (また、挿入時に数字を引用しないでください) – Glenn

+0

コメントは少し長くなっています、更新された答えを見てください。 – Glenn

関連する問題