Триггер выдает ошибку нарушения первичного ключа: невозможно вставить дубликат ключа в объект - PullRequest
0 голосов
/ 29 апреля 2020
create table Hotel
(
    hotel_id integer primary key NOT NULL,    
    hotel_name varchar(50) NOT NULL UNIQUE,
    location_ varchar(50) NOT NULL,
    rates varchar(10) check(rates in ('5star','4star','3star','2star','1star')),    
);    

create table Room
(
    room_no integer primary key NOT NULL,
    total_rooms integer NOT NULL,
    room_price real check (room_price >= 0),
    hotel_id integer foreign key references Hotel
);    

insert into Hotel values(1,'sevensay','gamapaha','4star')
insert into Hotel values(2,'sarasvi','gamapaha','3star')
insert into Hotel values(3,'galadari','colombo','5star')
insert into Hotel values(4,'kingsbary','colombo','4star')
insert into Hotel values(5,'niramliii','gamapaha','5star')
insert into Hotel values(6,'sadalnka','kandy','3star')
insert into Hotel values(7,'sri lnkani','kandy','5star')

insert into Room values(100,10000,1)
insert into Room values(220,20000,2)
insert into Room values(160,1000,3)
insert into Room values(100,12000,4)
insert into Room values(50,15000,5)
insert into Room values(80,10000,6)
insert into Room values(100,20000,7)

drop table Room
drop table Hotel

select * from Hotel
select * from Room

create trigger rooms_availability
on Room
for insert
as
begin    
    declare @hotel_id integer
    declare @total_rooms integer     

    select @hotel_id = hotel_id from  inserted
    select @total_rooms = count(*) from Room where hotel_id = @hotel_id
    rollback transaction

    if @total_rooms > 80    
    begin    
        print 'we have only 80 rooms .we cannot book the other rooms'   
    end
end

insert into Room values(300,10000,6)

Как я могу обработать эту ошибку?

Msg 2627, Уровень 14, Состояние 1, Строка 25
Нарушение ограничения PRIMARY KEY 'PK__Room__1967F4191F8BEC00'. Невозможно вставить дубликат ключа в объект 'dbo.Room'. Значение дубликата ключа: (506).
Оператор завершен.

1 Ответ

0 голосов
/ 29 апреля 2020

Отображаемая ошибка вызвана попыткой вставить строку в Room с дублированным первичным ключом. Однако код, который вы предоставляете, не имеет этой ошибки. И если вы используете столбец identity (рекомендуется для первичных ключей), у вас никогда не возникнет этой проблемы.

Более важная проблема заключается в вашем триггере, где вы не обрабатываете этот факт что Inserted может иметь несколько строк. Вы можете справиться с этим правильно, используя подход, основанный на множестве:

create trigger rooms_availability
on Room
for insert
as
begin    
    if exists (
      select 1
      from Room
      where hotel_id in (select hotel_id from Inserted)
      group by hotel_id
      having count(*) > 80
    )
    begin
        print 'We have only 80 rooms. We cannot book the other rooms.'   
        rollback;
    end;
end

Примечание: я предполагаю, что Print используется для отладки. Как только он заработает, вы захотите использовать throw .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...