Триггер работает не так, как нужно

CREATE TRIGGER i_checking_date_and_time_Observable_galaxies
ON [dbo].[Observable_galaxies]
FOR INSERT
AS
BEGIN
    DECLARE @Date_observation DATE = (SELECT Date_observation FROM inserted),
    @Time_start_observation TIME = (SELECT Time_start_observation FROM inserted),
    @Time_over_observation TIME = (SELECT Time_over_observation FROM inserted)
    DECLARE @ttt INT = (SELECT COUNT(*) FROM Observable_galaxies WHERE Date_observation = @Date_observation)
    PRINT(@ttt)
    IF (SELECT COUNT(*) FROM Observable_galaxies WHERE Date_observation = @Date_observation) = 1 OR
    (SELECT COUNT(*) FROM Observable_stars WHERE Date_observation = @Date_observation) = 1
    BEGIN
        PRINT('На эту дату уже зарегистрировано наблюдение.')
        ROLLBACK TRANSACTION
    END
    IF (@Time_start_observation < @Time_over_observation AND GETDATE() > @Date_observation)
    BEGIN
        PRINT('Дата или время введено неверно.')
        ROLLBACK TRANSACTION
    END
END
GO

Вот сам триггер, проблема в том, что вот этот запрос SELECT COUNT(*) FROM Observable_galaxies WHERE Date_observation = @Date_observation возвращает 1, но таблица пуста. Ниже таблица, на которую и сделан триггер.

CREATE TABLE Observable_galaxies
(
    ID_observation INT IDENTITY(1, 1) PRIMARY KEY,
    ID_galaxy INT FOREIGN KEY REFERENCES Famous_galaxies(ID_galaxy) NOT NULL,
    ID_group INT FOREIGN KEY REFERENCES Groups(ID_group) NOT NULL,
    Date_observation DATE NOT NULL,
    Time_start_observation TIME NOT NULL,
    Time_over_observation TIME NOT NULL
)
GO

И таблица по условию.

CREATE TABLE Observable_stars
(
    ID_observation INT IDENTITY(1, 1) PRIMARY KEY,
    ID_star INT FOREIGN KEY REFERENCES Famous_stars(ID_star) NOT NULL,
    ID_group INT FOREIGN KEY REFERENCES Groups(ID_group) NOT NULL,
    Date_observation DATE NOT NULL,
    Time_start_observation TIME NOT NULL,
    Time_over_observation TIME NOT NULL
)
GO

Что же я хочу сделать? Мне нужно перед вставкой данных проверять есть ли в обоих таблицах запись на ту же дату, и если есть - делать rollback.


Ответы (1 шт):

Автор решения: koshe

Проблема в том, что в count(*) включается еще и вставляемая строка, по этому эту строку нужно исключить. К тому же, ROLLBACK TRANSACTION не совсем корректно, так как у вас нет транзакции, нужно писать просто ROLLBACK:

CREATE TRIGGER i_checking_date_and_time_Observable_galaxies
ON [dbo].[Observable_galaxies]
FOR INSERT
AS
BEGIN
    DECLARE @Date_observation DATE = (SELECT Date_observation FROM inserted),
    @Time_start_observation TIME = (SELECT Time_start_observation FROM inserted),
    @Time_over_observation TIME = (SELECT Time_over_observation FROM inserted),
    @ID_observation int=(SELECT ID_observation FROM inserted)
    DECLARE @ttt INT = (SELECT COUNT(*) FROM Observable_galaxies WHERE Date_observation = @Date_observation)
    PRINT(@ttt)
    IF (SELECT COUNT(*) FROM Observable_galaxies WHERE Date_observation = @Date_observation and ID_observation<>@ID_observation) = 1 OR
    (SELECT COUNT(*) FROM Observable_stars WHERE Date_observation = @Date_observation) = 1
    BEGIN
        PRINT('На эту дату уже зарегистрировано наблюдение.')
        ROLLBACK
    END
    IF (@Time_start_observation < @Time_over_observation AND GETDATE() > @Date_observation)
    BEGIN
        PRINT('Дата или время введено неверно.')
        ROLLBACK 
    END
END
GO
→ Ссылка