SQL 服务器触发器认为 table 中存在重复,但实际上没有

SQL Server trigger thinks there's a duplicate in the table when there isn't

我是一名新 SQL 开发人员。根据建议,我改变了我的触发器(为此任务我需要使用触发器所以无法避免),但我已经重新改变了我的触发器。我希望它能防止其中包含的 BikeID 外键的 Rentals table 重复。

这是我目前的代码:

CREATE TRIGGER BikeNotAvailable 
ON dbo.SA_Rental
AFTER INSERT
AS
    IF EXISTS (SELECT * 
               FROM SA_Rental
               INNER JOIN inserted i ON i.BikeID = dbo.SA_Rental.BikeID)
    BEGIN
        ROLLBACK
        RAISERROR ('This bike is already being hired', 16, 1);
    END
go

但是当我在 Rentals table 中输入 BikeID 时,即使 BikeID 不在一行中,它仍然会引发错误 -为什么? (我也在空的 table 上测试过这个,它仍然会引发错误)

只是关于我的数据的一些上下文,BikeID 是来自 'Bike' table 的主键,作为外键共享到 Rentals table,不确定这是否与错误有关。

谁能帮我修复这个触发器,让它工作。

谢谢。

好吧,因为它是一个 AFTER 触发器,触发器是 运行 新记录添加到 table 之后(至少对您的可见触发器)。

假设您的 table 有一个自动生成的 ID 列,您应该像这样从检查中排除插入的行:

CREATE TRIGGER BikeNotAvailable ON dbo.SA_Rental
AFTER INSERT
AS
  if exists ( select * from SA_Rental
  inner join inserted i on i.BikeID=dbo.SA_Rental.BikeID
  where SA_Rental.RentalID <> i.RentalID)
  begin
    rollback
    RAISERROR ('This bike is already being hired', 16, 1);
  end
go

一个更简单的方法来实现你所追求的是创建一个唯一索引:

CREATE UNIQUE INDEX BikeRented ON SA_Rental (BikeID);

当然,这 假设 当自行车不再租用时,您从 table 中删除了该行(因为这是您 post).如果不是这种情况,那么我们需要更多细节;在您的 table 上说明租赁已完成的是什么?

如果我们假设你有一个return日期,return日期是NULL 当自行车尚未 returned 时,您将使用如下过滤索引:

CREATE UNIQUE INDEX BikeRented ON SA_Rental (BikeID)
WHERE ReturnedDate IS NULL;