Триггер SQL с условными обновлениями - PullRequest
0 голосов
/ 18 января 2012

Мне нужно построить следующую логику на паре таблиц SQL.Вот базовая структура таблицы:

TABLE [dbo].[Email](
    [IssueId] [int] NOT NULL,
    [NoErrors] [int] NOT NULL,
    [EmailBody] [nvarchar](max) NULL,
    ...
)

TABLE [dbo].[Inclusion](
    [InclusionId] [int] IDENTITY(1,1) NOT NULL,
    [IssueId] [int] NOT NULL,
    ...
)

Основным отношением для обеих таблиц является таблица [Issue] в поле IssueId.Каждая запись выпуска имеет только одну связанную таблицу электронной почты, но от нуля до многих записей включения.

Я хочу, чтобы это произошло ...

Если запись включения удалена и она была последнейВключение записи, связанной с проблемой, затем я хочу установить для Email.NoErrors значение -1.Если существуют другие Включения (после удаления), я хочу оставить Email.NoErrors «как есть».

Я написал следующий триггер, который, похоже, работает:две вещи, о которых я знаю достаточно, чтобы беспокоитьсяВо-первых, триггер кажется неэффективным, поскольку он всегда обновляет поле Email.NoErrors, даже если это не нужно.Во-вторых, я знаю, что справочная таблица DELETED может содержать более одной записи, но я не уверен, будет ли мой сценарий обрабатывать это правильно - но я подозреваю, что нет.

ОБНОВЛЕНИЕ
Вот окончательный код, с которым я закончил:

ALTER TRIGGER [dbo].[trg_Inclusion_Delete]
   ON  [dbo].[Inclusion] AFTER DELETE
AS 

IF @@ROWCOUNT = 1
BEGIN
   UPDATE Issue
   SET NoEmailErrors = -1
   FROM DELETED
   WHERE (
      Issue.IssueId = DELETED.IssueId
      AND Issue.NoEmailErrors != -1
      AND NOT EXISTS (
         SELECT * 
         FROM Inclusion
         WHERE Inclusion.IssueId = DELETED.IssueId
      )
   )
END
ELSE
BEGIN
   UPDATE Issue
   SET NoEmailErrors = -1
   FROM DELETED
   WHERE (
      Issue.IssueId IN (
         SELECT IssueId FROM DELETED
      )
      AND Issue.NoEmailErrors != -1
      AND NOT EXISTS (
         SELECT * 
         FROM Inclusion
         WHERE Inclusion.IssueId = DELETED.IssueId
      )
   )
END

1 Ответ

1 голос
/ 19 января 2012

Это переписывание может помочь вам с проблемой неэффективности:

ALTER TRIGGER [dbo].[trg_Inclusion_Delete]
    ON [dbo].[Inclusion]
    AFTER DELETE
AS 
BEGIN
SET NOCOUNT ON;

    UPDATE Email
    SET NoErrors = -1
    FROM DELETED
    WHERE Email.IssueId = DELETED.IssueId
        AND NOT EXISTS
        (
            SELECT 'x' FROM Inclusion 
            WHERE Inclusion.IssueId = DELETED.IssueId
        )
END
...