Триггер SQL Server не работает должным образом - PullRequest
0 голосов
/ 26 апреля 2018

У меня есть две таблицы:

CREATE TABLE [dbo].[Test_Table1]
(
    [id] [int] IDENTITY(1,1) NOT NULL,
    [f_id] [int] NULL
) ON [PRIMARY]

CREATE TABLE [dbo].[Test_Table2_Tbl]
(
    [f_id] [int] IDENTITY(1,1) NOT NULL,
    [text] [varchar](500) NULL
) ON [PRIMARY]

И триггер:

CREATE TRIGGER [dbo].[trg_Test_Trigger_Delete]
ON [dbo].[Test_Table2_Tbl] 
AFTER DELETE
AS
    INSERT INTO Test_Table2_Tbl (text)
        (SELECT id FROM deleted)

    UPDATE Test_Table1_Tbl
    SET f_id = NULL
    WHERE f_id IN (SELECT id FROM deleted)
GO

Заинтересованный наблюдатель поймет, что «id» не существует в «удалено».

SQL ловит эту ошибку в INSERT, но без INSERT она позволит вам добавить триггер без каких-либо жалоб.

Почему он не ловит эту ошибку? (Неверное имя столбца 'id'.)

Мой второй вопрос: почему оператор UPDATE обновляет столбец EVERY до NULL, если идентификатор не найден в удаленном?

Я просто очень запутался, и мне нужна ясность, почему каждая запись соответствует этому предложению WHERE.

1 Ответ

0 голосов
/ 26 апреля 2018

Ваша ошибка в UPDATE связана с тем, что запрос обрабатывается как коррелированный подзапрос:

UPDATE Test_Table1_Tbl
    SET f_id = NULL
    WHERE Test_Table1_Tbl.f_id IN (SELECT Test_Table1_Tbl.id FROM deleted d);

id не разрешается в deleted, поэтому SQL смотрит на следующий уровень.

Это общие правила для подзапросов. Вот почему вы должны всегда использовать квалифицированные имена таблиц, когда у вас есть подзапросы:

UPDATE Test_Table1_Tbl
    SET f_id = NULL
    WHERE Test_Table1_Tbl.f_id IN (SELECT d.id FROM deleted d);
...