SQL - удалить обновленную строку в триггере обновления - PullRequest
2 голосов
/ 02 апреля 2012

У меня проблема с моим триггером обновления

ALTER TRIGGER tr_MyTable
ON  MyTable
AFTER UPDATE
AS 

BEGIN TRAN
SET NOCOUNT ON;

      If Update(column)
      Begin
           DELETE FROM MyTable WHERE <condition>
      End


      SET NOCOUNT OFF
COMMIT TRAN
GO

Я пытаюсь удалить строку (из MayTable), которая в данный момент обновлена ​​в MyTable.Но строка не удаляется при запуске триггера.Разве невозможно удалить строку, которая в данный момент обновлена ​​внутри триггера обновления?(Удаление и обновление находятся в одной таблице)

Спасибо!

РЕДАКТИРОВАТЬ:

ALTER TRIGGER tr_MyTable
ON  MyTable
AFTER UPDATE
AS 

BEGIN TRAN
SET NOCOUNT ON;

      SELECT @ID = ID
      FROM   inserted

      If Update(column)
      Begin
           DELETE FROM MyTable WHERE ID = @ID
      End


      SET NOCOUNT OFF
COMMIT TRAN
GO

РЕДАКТИРОВАТЬ 2:

ALTER PROCEDURE sp_Update
(
@ID INTEGER,)
AS

SET NOCOUNT ON
Begin Tran

            Update MyTable SET Column = Data where ID = @ID

      Commit Tran
SET NOCOUNT OFF
GO

Это обновлениеProsedure работает и колонка обновляется.Триггер также срабатывает, и выполняется строка перед удалением (оператор print), но не оператор delete.Но когда я обновляю столбец непосредственно в таблице, не формирую процедуру, запускается триггер, и оператор удаления работает так, как должен. Я не использую откат.

Ответы [ 3 ]

2 голосов
/ 02 апреля 2012

Может быть, вы хотите сделать это в триггере INSTEAD OF. Если кто-то попытается обновить этот столбец, вы можете удалить строку, в противном случае вы повторно выполните обновление. Единственная проблема здесь заключается в том, что вы должны перекодировать оператор обновления в триггере. (Кроме того, вам на самом деле не нужен дополнительный BEGIN TRAN / COMMIT TRAN внутри триггера.)

CREATE TRIGGER dbo.tr2_myTable
ON dbo.MyTable
INSTEAD OF UPDATE
AS
BEGIN
  SET NOCOUNT ON;

  -- update the rows where the column hasn't changed
  UPDATE s
    SET col1 = i.col1, col2 = i.col2, ...
    FROM dbo.MyTable AS s
    INNER JOIN inserted AS i
    ON s.key = i.key
    INNER JOIN deleted AS d
    ON i.key = d.key
    AND i.column_that_should_not_change = d.column_that_should_not_change;

  -- delete the rows where the column HAS changed
  -- (note that this requirement sounds odd to me)
  DELETE s
    FROM dbo.MyTable AS s
    INNER JOIN inserted AS i
    ON s.key = i.key
    INNER JOIN deleted AS d
    ON i.key = d.key
    AND i.column_that_should_not_change <> d.column_that_should_not_change;
END
GO

Обратите внимание, что в отличие от вашей логики IF UPDATE(), этот триггер будет фактически обрабатывать несколько строк (например, некоторые, где этот столбец изменился, а некоторые, где он не изменился). Обратите внимание, что IF UPDATE(x) будет истинным, даже если кто-то сказал UPDATE foo SET x = x;.

Предполагается, что у вас есть ключевой столбец, и что column_that_should_not_change не может быть пустым. Если этот столбец допускает значения NULL, тогда логика становится немного более сложной.

2 голосов
/ 02 апреля 2012

как вы удаляете .?

вы должны читать свои значения из таблиц INSERTED и DELETED, например:

DELETE FROM MyTable WHERE id in (select ID from INSERTED)
1 голос
/ 02 апреля 2012

Возможно.

Если вы хотите, вы можете иметь DELETE FROM MyTable в вашем триггере, и это должно работать. Вы проверяли, чтобы убедиться, что триггер выполняется и ваш код достигает строки DELETE FROM MyTable WHERE <condition>?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...