SQL Server 2008 несколько вставок над 2 таблицами - PullRequest
1 голос
/ 27 апреля 2010

Я получил следующий триггер в моей базе данных 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

Триггер выдает ошибки при попытке выполнить запрос ниже.Этот запрос я должен добавить двух разных пассажиров в базу данных на двух разных рейсах.Я уверен, что оба места не заняты, но я не могу понять, почему триггер дает мне ошибку.Нужно ли что-то делать с корреляцией?

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')

ОБНОВЛЕНИЕ: Таблица выглядит следующим образом

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
)

Ответы [ 3 ]

6 голосов
/ 27 апреля 2010

Есть несколько проблем с этим подзапросом:

SELECT 1
FROM Passenger p 
INNER JOIN Inserted i on i.flight= p.flight
WHERE p.flight= i.flight AND p.seat= i.seat

Прежде всего, WHERE p.flight = i.flight совершенно не нужен, так как он уже является частью вашего объединения.

Во-вторых, p.seat = i.seat также должен быть частью JOIN.

В-третьих, этот триггер запускается после строки были вставлены, так что это будет всегда совпадение, и поэтому ваш триггер всегда вызовет ошибку и бросит назад.

Вы можете исправить триггер, но гораздо лучшим способом было бы вообще не использовать триггер. Если я понимаю, что вы пытаетесь сделать правильно, все, что вам нужно, это ограничение UNIQUE на flight, seat:

ALTER TABLE passgier
ADD CONSTRAINT IX_passagier_flightseat
UNIQUE (flight, seat)
2 голосов
/ 27 апреля 2010

Если запустить триггер после вставки записи, а затем искать запись со значениями, которые вы только что вставили, вы всегда найдете ее. Вы можете попробовать триггер INSTEAD OF, чтобы проверить существующие записи перед выполнением вставки.

0 голосов
/ 27 апреля 2010

Возможно, выдает ошибку, найдя себя в таблице (циклическая ссылка на себя). Возможно, вы захотите добавить дополнительный фильтр к предложению where, например «AND Passenger.ID <> вставлен. ID»

...