Rob*_*Rob 1 sql triggers insert sql-server-2008
我的sql server 2008数据库上有以下触发器
CREATE TRIGGER tr_check_stoelen
ON Passenger
AFTER INSERT, UPDATE
AS
BEGIN
IF EXISTS(
SELECT 1
FROM Passenger p
INNER JOIN Inserted i on i.flight= p.flight
WHERE p.flight= i.flightAND p.seat= i.seat
)
BEGIN
RAISERROR('Seat taken!',16,1)
ROLLBACK TRAN
END
END
Run Code Online (Sandbox Code Playgroud)
当我尝试运行下面的查询时触发器抛出错误.这个查询我应该在两个不同的航班上的数据库中插入两个不同的乘客.我确定两个座位都没有被占用,但我无法弄清楚为什么触发器会给我错误.是否必须对相关做一些事情?
INSERT INTO passagier VALUES
(13392,5315,3,'Janssen Z','2A','October 30, 2006 10:43','M'),
(13333,5316,2,'Janssen Q','2A','October 30, 2006 11:51','V')
Run Code Online (Sandbox Code Playgroud)
更新:该表如下所示
CREATE TABLE Passagier
(
passengernumber int NOT NULL CONSTRAINT PK_passagier PRIMARY KEY(passagiernummer),
flight int NOT NULL CONSTRAINT FK_passagier_vlucht REFERENCES vlucht(vluchtnummer)
ON UPDATE NO ACTION ON DELETE NO ACTION,
desk int NULL CONSTRAINT FK_passagier_balie REFERENCES balie(balienummer)
ON UPDATE NO ACTION ON DELETE NO ACTION,
name varchar(255) NOT NULL,
seat char(3) NULL,
checkInTime datetime NULL,
gender char(1) NULL
)
Run Code Online (Sandbox Code Playgroud)
这个子查询存在一些问题:
SELECT 1
FROM Passenger p
INNER JOIN Inserted i on i.flight= p.flight
WHERE p.flight= i.flight AND p.seat= i.seat
Run Code Online (Sandbox Code Playgroud)
首先,这WHERE p.flight = i.flight是非常不必要的,因为它已经是你加入的一部分.
其次,p.seat = i.seat也应该是其中的一部分JOIN.
第三,此触发器在插入行之后运行,因此它将始终匹配,因此您的触发器将始终引发错误并回滚.
您可以修复触发器,但更好的方法是根本不使用触发器.如果我理解你正在尝试做的事情,你所需要的只是一个UNIQUE约束flight, seat:
ALTER TABLE passgier
ADD CONSTRAINT IX_passagier_flightseat
UNIQUE (flight, seat)
Run Code Online (Sandbox Code Playgroud)