Триггеры SQL - удалены или обновлены?или может что то еще? - PullRequest
0 голосов
/ 25 июля 2011

Я пытаюсь выяснить, что мне нужно использовать здесь: удалено, вставлено или обновлено.

в основном.

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

Это то, что у меня сейчас:

ALTER TRIGGER [dbo].[trg_SourceHistory]  ON [dbo].[tblSource]
FOR UPDATE AS  
    DECLARE @statusOldValue char(1) 
    DECLARE @statusNewValue char(1)

    SELECT @statusOldValue = statusCode FROM deleted 
    SELECT @statusNewValue= statusCode FROM updated

    IF (@statusOldValue <> @statusNewValue) AND 
       (@statusOldValue = 'P' or @statusOldValue = 'A')
    BEGIN TRY
       INSERT * INTO tblHistoryTable)  
           select * from [DELETED]

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

Ответы [ 3 ]

7 голосов
/ 25 июля 2011

Есть только псевдотаблицы Inserted и Deleted - Updated нет.

Для UPDATE, Inserted содержит новые значения (после обновления), в то время как Deleted содержит старые значения до обновления.

Также следует помнить , что триггеры срабатывают один раз за пакет - не один раз для каждой строки.Таким образом, обе псевдотаблицы могут содержать несколько строк !Не просто примите одну строку и присвойте ее переменной - это

SELECT @statusOldValue = statusCode FROM deleted 
SELECT @statusNewValue= statusCode FROM updated

завершится ошибкой , если у вас несколько строк!Вы должны написать свои триггеры таким образом, чтобы они работали с несколькими строками в Inserted и Deleted!

Обновление: да - там IS гораздо лучший способ написать это:

ALTER TRIGGER [dbo].[trg_SourceHistory]  ON [dbo].[tblSource]
FOR UPDATE 
AS  
   INSERT INTO dbo.tblHistoryTable(Col1, Col2, Col3, ...., ColN)
      SELECT Col1, COl2, Col3, ..... ColN
        FROM Deleted d
        INNER JOIN Inserted i ON i.PrimaryKey = d.PrimaryKey
        WHERE i.statusCode <> d.statusCode
          AND d.statusCode IN ('A', 'P')

В основном:

  • явно указать столбцы, которые вы хотите вставить - оба в INSERT оператор, а также оператор SELECT, извлекающий данные для вставки - чтобы избежать неприятных сюрпризов

  • создайте INNER JOIN между Inserted и Deleted псевдотаблицами дляполучить все строки, которые были обновлены

  • указать все другие условия (различные коды состояния и т. д.) в предложении WHERE SELECT

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

5 голосов
/ 25 июля 2011

Вам необходимо использовать обе таблицы inserted и deleted для проверки записей, которые:
1. Уже существует (чтобы проверить, что это не вставка)
2. По-прежнему существует (чтобы проверить, что это не удаление)
3. Поле статуса изменено

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

INSERT INTO
  tblHistoryTable
SELECT
  deleted.*
FROM
  inserted
INNER JOIN
  deleted
    ON inserted.PrimaryKey = deleted.PrimaryKey
WHERE
  inserted.StatusCode <> deleted.StatusCode
  AND (inserted.StatusCode = 'P' OR inserted.StatusCode = 'A')
  • вставлено = новые значения
  • удалено = старые значения
1 голос
/ 25 июля 2011

Нет таблицы updated, которую вы ищете inserted.

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