Обновлено значение в SQL Server, особенно в SQL Server 2005 - PullRequest
0 голосов
/ 02 октября 2011

Как можно обнаружить обновленное значение в триггере, особенно в SQL Server 2005?

Ответы [ 4 ]

1 голос
/ 02 октября 2011

Обратите внимание, что вы не должны пытаться получить значение, потому что триггеры должны быть закодированы, чтобы иметь дело с несколькими изменениями строки

Тем не менее, вы можете использовать специальные таблицы DELETED и INSERTED

CREATE TRIGGER TRG_SomeTable_U ON dbo.SomeTable AFTER UPDATE 
AS 

-- DECLARE @ TABLE ...
-- INSERT HistoryTable
-- whatever

SELECT
    ...
FROM
   INSERTED I
   JOIN
   UPDATED U ON I.PK 0 U.PK
WHERE
  I.SomeColumn <> U.SomeColumn -- does not handle NULLs
GO
1 голос
/ 02 октября 2011

Самое простое решение использует триггеры.Посмотрите на его пример.Может быть, поможет вам.Кроме того, вы можете найти несколько комментариев в исходном коде.

--Test initialization
CREATE TABLE dbo.[Transaction]
(
    ID INT IDENTITY(1,1) PRIMARY KEY,
    InsertDateTime DATETIME NOT NULL DEFAULT GETDATE(),
    [Date] DATETIME,
    CustomerID VARCHAR(50),
    [Type] VARCHAR(3),
    Amount MONEY
);
GO

INSERT INTO [Transaction]([Date],CustomerID,[Type],Amount)
SELECT '2011-01-01','CUST1001','INV','12,000' UNION ALL
SELECT '2011-01-02','CUST1001','PAY','3,000' UNION ALL
SELECT '2011-01-03','CUST1001','INV','8,000' UNION ALL
SELECT '2011-01-04','CUST1001','PAY','9,000' UNION ALL
SELECT '2011-01-04','CUST1002','INV','1,000' UNION ALL
SELECT '2011-01-05','CUST1002','PAY','5,000' UNION ALL
SELECT '2011-01-05','CUST1002','INV','6,000';
GO

CREATE TABLE AuditTransaction
(
     AuditID INT IDENTITY(1,1) PRIMARY KEY
    ,UpdateDateTime DATETIME NOT NULL DEFAULT GETDATE()
    ,ID INT NOT NULL
    ,[Date] DATETIME NULL
    ,CustomerID VARCHAR(50) NULL
    ,[Type] VARCHAR(3) NULL
    ,Amount MONEY NULL
);
GO

CREATE TRIGGER trgI_Transaction_Logging
ON dbo.[Transaction]
AFTER UPDATE
AS
BEGIN
    SET NOCOUNT ON;
    --Will be inserted only the old values (d.* = deleted.*) . Otherwise NULL will be inserted.
    INSERT  dbo.AuditTransaction(ID,[Date],CustomerID,[Type],Amount)
    SELECT  i.ID
            --If the old value (d.[Date]) and the new one (i.[Date]) are both equals 
            --then "NULL" 
            --else "old value" (d.[Date])
            ,NULLIF(d.[Date],i.[Date])
            ,NULLIF(d.CustomerID,i.CustomerID)
            ,NULLIF(d.[Type],i.[Type])
            ,NULLIF(d.Amount,i.Amount)
    FROM    deleted d INNER JOIN inserted i ON d.ID=i.ID;
END;
GO
--End of Test initialization

--Test: run UPDATEs
WAITFOR DELAY '00:00:01'; 
UPDATE  dbo.[Transaction] 
SET     Amount = Amount + 5
WHERE   ID = 1;
--1 second delay between UPDATEs
WAITFOR DELAY '00:00:01'; 
UPDATE  dbo.[Transaction] 
SET     Amount = Amount + 9
        ,[Date] = '2011-01-02 22:22:22'
WHERE   ID = 2;
WAITFOR DELAY '00:00:01';
UPDATE  dbo.[Transaction] 
SET     Amount = Amount + 9
        ,[Date] = '2011-01-02 11:11:11'
WHERE   ID = 1;
WAITFOR DELAY '00:00:01';
UPDATE  dbo.[Transaction] 
SET     Amount = Amount + 10
WHERE   ID = 3;
WAITFOR DELAY '00:00:01';
UPDATE  dbo.[Transaction] 
SET     Amount = Amount + 20
WHERE   ID = 4;
WAITFOR DELAY '00:00:01';
UPDATE  dbo.[Transaction] 
SET     CustomerID = NULL
WHERE   ID = 5;
--End of UPDATEs

PRINT 'dbo.AuditTransaction content'
SELECT  *
FROM    dbo.AuditTransaction at;

--Test: checking ”log” (audit table) for the first transaction
DECLARE @TransactioID INT;
SELECT  @TransactioID = 1;
PRINT 'Transaction 1 history'
SELECT  'I' AS OperationType, t.[InsertDateTime] OperationDateTime, 0 AS AuditID
        ,t.ID, t.[Date], t.CustomerID, t.[Type], t.Amount
FROM    dbo.[Transaction] t
WHERE   t.ID = @TransactioID 
UNION ALL
SELECT  'U' AS OperationType, at.UpdateDateTime, at.AuditID
        ,at.ID, at.[Date], at.CustomerID, at.[Type], at.Amount
FROM    dbo.AuditTransaction at
WHERE   at.ID = @TransactioID 
ORDER BY OperationType DESC, OperationDateTime;
--End of test

--By, by
DROP TABLE dbo.AuditTransaction;
DROP TABLE dbo.[Transaction];
GO

Результаты:

dbo.AuditTransaction content
AuditID     UpdateDateTime          ID          Date                    CustomerID                                         Type Amount
----------- ----------------------- ----------- ----------------------- -------------------------------------------------- ---- ---------------------
1           2011-10-02 13:48:22.683 1           NULL                    NULL                                               NULL 12000,00
2           2011-10-02 13:48:23.677 2           2011-01-02 00:00:00.000 NULL                                               NULL 3000,00
3           2011-10-02 13:48:24.680 1           2011-01-01 00:00:00.000 NULL                                               NULL 12005,00
4           2011-10-02 13:48:25.680 3           NULL                    NULL                                               NULL 8000,00
5           2011-10-02 13:48:26.683 4           NULL                    NULL                                               NULL 9000,00
6           2011-10-02 13:48:27.683 5           NULL                    CUST1002                                           NULL NULL

(6 row(s) affected)

Transaction 1 history
OperationType OperationDateTime       AuditID     ID          Date                    CustomerID                                         Type Amount
------------- ----------------------- ----------- ----------- ----------------------- -------------------------------------------------- ---- ---------------------
U             2011-10-02 13:56:41.420 1           1           NULL                    NULL                                               NULL 12000,00
U             2011-10-02 13:56:43.430 3           1           2011-01-01 00:00:00.000 NULL                                               NULL 12005,00
I             2011-10-02 13:56:40.363 0           1           2011-01-02 11:11:11.000 CUST1001                                           INV  12014,00

(3 row(s) affected)

Как можно интерпретировать эти результаты?Строки 'I' содержат фактические значения, а строки 'U' содержат старые значения.

Пример:

  1. Для поля Amount первое значение было 12014, а последнеезначение 12014.
  2. CustomerID поле не изменено.
  3. [Date] поле изменено с 2011-01-01 00:00:00.000 на 2011-01-02 11:11:11.000 на 2011-10-02 13:56:43.430.
1 голос
/ 02 октября 2011
IF UPDATE (mycol1) 

например.

CREATE TRIGGER reminder
ON Person.Address
AFTER UPDATE 
AS 
IF ( UPDATE (StateProvinceID) OR UPDATE (PostalCode) )
BEGIN
    RAISERROR (50009, 16, 10)
END;
GO

Ref .

Если вы ссылаетесь на фактические значения, они хранятся в таблицах inserted и deleted. См. Использование вставленных и удаленных таблиц

0 голосов
/ 05 октября 2011

Я нашел этот ответ верным !!Триггер UPDATE используется для выполнения действия после обновления таблицы.

CREATE TRIGGER tr_Orders_UPDATE
ON Orders
AFTER UPDATE
AS

--Make sure Priority was changed
IF NOT UPDATE(Ord_Priority)
RETURN

--Determine if Priority was changed to high
IF EXISTS (SELECT *
       FROM INSERTED a
   JOIN DELETED b ON a.Ord_ID=b.Ord_ID
   WHERE b.Ord_Priority <> 'High' AND
   a.Ord_Priority = 'High')
BEGIN
DECLARE @Count tinyint
SET @Count = (SELECT COUNT(*)
            FROM INSERTED a
    JOIN DELETED b ON a.Ord_ID=b.Ord_ID
    WHERE b.Ord_Priority <> 'High' AND
    a.Ord_Priority = 'High')
PRINT CAST(@Count as varchar(3))+' row(s) where changed to a priority of High'
END
go

В части I триггер INSERT отслеживал заказы с приоритетом «Высокий».Триггер UPDATE отслеживает заказы, приоритет которых изменен с чего-то другого на Высокий.

Оператор IF проверяет, изменилось ли значение Ord_Priority.Если нет, мы можем сэкономить некоторое время, немедленно выйдя из триггера.

Удаленная таблица содержит значения до ОБНОВЛЕНИЯ, а вставленная таблица содержит новые значения.Когда таблицы объединены, легко определить, когда приоритет меняется с чего-то другого на Высокий.

Ссылка

...