触发器引发主键冲突错误:无法在对象中插入重复的键

问题描述 投票:0回答:1
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行违反主键约束'PK__Room__1967F4191F8BEC00'。无法在对象“ dbo.Room”中插入重复键。重复密钥值为(506)。该语句已终止。

sql-server database-trigger
1个回答
0
投票

您显示的错误是由于尝试使用重复的主键将行插入Room而引起的。但是,您提供的代码没有该错误。而且,如果使用identity列(推荐用于主键),则永远不会出现该问题。

更重要的问题是在触发器中,您没有在处理identity可以有多行的事实。您可以使用基于集合的方法来正确处理此问题:

Inserted

注意:我假设正在使用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

© www.soinside.com 2019 - 2024. All rights reserved.