Как переместить обновленную запись в таблицу истории? - PullRequest
2 голосов
/ 26 июля 2010

У меня есть следующая таблица:

CREATE TABLE FE_USER
(
    userid int identity (321,4) CONSTRAINT userid_pk PRIMARY KEY,
    username varchar(40)
);

Соответствующая ему таблица истории:

CREATE TABLE FE_USER_HIST
(
    userid int,
    username varchar(40),
    v_action varchar(50)
);

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

Как мне написать триггер в t-sql?

Вот мой псевдокод, но я получаю много ошибок:

CREATE OR REPLACE TRIGGER user_to_hist
    AFTER UPDATE OR DELETE
    ON FE_USER
    FOR EACH ROW
    DECLARE
        v_action varchar(50);
    BEGIN
        v_action := CASE WHEN UPDATING THEN 'UPDATE' ELSE 'DELETE' END;
        INSERT INTO FE_USER_HIS(userid, username, v_action)
        SELECT :OLD.userid, :OLD.username, v_action
        FROM .......;
END;

Ответы [ 2 ]

5 голосов
/ 26 июля 2010

SQL Server не поддерживает, к сожалению, CREATE OR REPLACE.Вам нужно использовать либо CREATE, либо ALTER в зависимости от того, какое действие вы делаете.

Также у него нет триггеров на уровне строк.Все затронутые строки доступны вам в псевдотаблицах с именами INSERTED или DELETED

. Самый простой способ - это два отдельных триггера.

Для вставки

CREATE TRIGGER dbo.tr_i_FE_USER 
   ON  dbo.FE_USER 
   AFTER INSERT
AS 
BEGIN
    SET NOCOUNT ON;
INSERT INTO FE_USER_HIST
SELECT userid,username, 'inserted' AS v_action
FROM INSERTED

END

И для обновления

CREATE TRIGGER dbo.tr_u_FE_USER 
   ON  dbo.FE_USER 
   AFTER UPDATE
AS 
BEGIN
    SET NOCOUNT ON;
INSERT INTO FE_USER_HIST
SELECT userid,username, 'updated' AS v_action
FROM INSERTED /*If you wanted the previous value instead
                 you could use FROM DELETED */

END

Просто следуя подходу, который я упомянул в комментариях

CREATE TRIGGER dbo.tr_iud_FE_USER 
   ON  dbo.FE_USER 
   AFTER INSERT, UPDATE, DELETE
AS 
BEGIN
    SET NOCOUNT ON;

    INSERT INTO FE_USER_HIST
    SELECT 
    ISNULL(i.UserId,d.UserId) AS UserId,

    CASE WHEN i.UserId IS NULL THEN d.UserName
         ELSE i.UserName
    END AS UserName,

    CASE WHEN i.UserId IS NULL THEN 'deleted' 
         WHEN d.UserId IS NULL THEN 'inserted' 
         ELSE 'updated'
    END  AS v_action
    from INSERTED i FULL OUTER JOIN DELETED d 
    ON i.UserId = d.USerId
END
2 голосов
/ 26 июля 2010

Если вы хотите захватить все 3 действия, я бы использовал 2 триггера вместо одного:

CREATE TRIGGER user_to_historyA ON FE_USER
AFTER INSERT, UPDATE 
AS
DECLARE @action varchar(50)
    SET @action = CASE WHEN UPDATE(username) THEN 'UPDATE' ELSE 'INSERT' END

    INSERT INTO FE_USER_HIS(userid, username, v_action)
    SELECT userid, username, @action
    FROM inserted

GO


CREATE TRIGGER user_to_historyB ON FE_USER
AFTER DELETE
AS
    INSERT INTO FE_USER_HIS(userid, username, v_action)
    SELECT userid, username, 'DELETE'
    FROM deleted

GO

РЕДАКТИРОВАТЬ (за правильный комментарий Мартина относительно использования бесполезной функции UPDATE () и объединения в 1 триггер)

    ALTER TRIGGER user_to_history ON FE_USER
    AFTER INSERT, UPDATE, DELETE 
    AS
    DECLARE @action varchar(50)
        IF EXISTS(SELECT username FROM inserted)
        BEGIN
            SET @action = CASE WHEN EXISTS(SELECT username FROM deleted) THEN 'UPDATE' ELSE 'INSERT' END

            INSERT INTO FE_USER_HIS(userid, username, v_action)
            SELECT userid, username, @action
            FROM inserted
        END
        ELSE
            INSERT INTO FE_USER_HIS(userid, username, v_action)
            SELECT userid, username, 'DELETE'
            FROM deleted
    GO
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...