Някои таблици на базата данни включват колона „последна модификация“, която съхранява датата и часа на последното актуализиране на реда. Всеки път, когато редът се актуализира, датата се актуализира, за да отразява датата и часа на тази актуализация.
В SQL Server можете да използвате тригер, за да извършите тази актуализация.
Тригерът е специален тип съхранена процедура, която се изпълнява автоматично, когато възникне събитие в сървъра на базата данни.
Можете да използвате CREATE TRIGGER
оператор за създаване на тригер при използване на T-SQL. Този израз може да се използва за създаване на DML, DDL или тригер за влизане.
Пример
Следният код създава таблица, както и тригер, който актуализира ModifiedDate
колона всеки път, когато има актуализация.
CREATE TABLE dbo.Books (
BookId int IDENTITY(1,1) NOT NULL PRIMARY KEY,
BookName nvarchar(1000) NOT NULL,
CreateDate datetime DEFAULT CURRENT_TIMESTAMP,
ModifiedDate datetime DEFAULT CURRENT_TIMESTAMP
);
CREATE TRIGGER trg_Books_UpdateModifiedDate
ON dbo.Books
AFTER UPDATE
AS
UPDATE dbo.Books
SET ModifiedDate = CURRENT_TIMESTAMP
WHERE BookId IN (SELECT DISTINCT BookId FROM inserted);
Вмъкване на ред
Нека вмъкнем ред и го изберете, за да видите резултата от DEFAULT
ограничение:
INSERT INTO Books (BookName)
VALUES ('Trigger Happy');
SELECT * FROM Books;
Резултат (с помощта на вертикален изход):
-[ RECORD 1 ]------------------------- BookId | 1 BookName | Trigger Happy CreateDate | 2020-08-17 23:33:15.230 ModifiedDate | 2020-08-17 23:33:15.230
Това се показва с помощта на вертикален изход, за да се улесни четенето (така че да не се налага да превъртате настрани, за да прочетете всички колони).
В този случай и двете CreatedDate
и ModifiedDate
колони съдържат една и съща стойност. Ако обаче редът се актуализира, ModifiedDate
Стойността на трябва да се промени. Ето защо създадохме спусъка.
Актуализиране на реда
Сега нека актуализираме реда и изберете резултатите.
UPDATE Books
SET BookName = 'Trigger Hippy'
WHERE BookId = 1;
SELECT * FROM Books;
Резултат (с помощта на вертикален изход):
-[ RECORD 1 ]------------------------- BookId | 1 BookName | Trigger Hippy CreateDate | 2020-08-17 23:33:15.230 ModifiedDate | 2020-08-18 00:07:39.680
Както се очакваше, ModifiedDate
колоната се актуализира, но CreateDate
колоната остава същата.
Допълнително обяснение на кода
По-долу е по-подробно обяснение на кода, използван за създаване на таблицата и свързания с нея тригер.
Таблицата
Следният код създава таблицата:
CREATE TABLE dbo.Books (
BookId int IDENTITY(1,1) NOT NULL PRIMARY KEY,
BookName nvarchar(1000) NOT NULL,
CreateDate datetime DEFAULT CURRENT_TIMESTAMP,
ModifiedDate datetime DEFAULT CURRENT_TIMESTAMP
);
ModifiedDate
колоната има DEFAULT
ограничение, което задава стойността по подразбиране на CURRENT_TIMESTAMP
(както и CreateDate
колона).
Това означава, че когато редът е вмъкнат за първи път, CURRENT_TIMESTAMP
се вмъква в тези колони.
Това е добре за първоначалното вмъкване, но не се грижи за последващи актуализации. Тук идва спусъкът.
Задействането
Следният код създава тригера:
CREATE TRIGGER trg_Books_UpdateModifiedDate
ON dbo.Books
AFTER UPDATE
AS
UPDATE dbo.Books
SET ModifiedDate = CURRENT_TIMESTAMP
WHERE BookId IN (SELECT DISTINCT BookId FROM inserted);
В този случай извиках тригера trg_Books_UpdateModifiedDate
.
Създадох го в dbo.Books
база данни и се изпълнява след всяка UPDATE
.
Когато се изпълнява, той актуализира ModifiedDate
колона в CURRENT_TIMESTAMP
(но само на реда, който е актуализиран, разбира се).
Мога да определя кой ред е актуализиран, като проверя inserted
маса. inserted
table е временна, резидентна таблица, която SQL Server създава и поддържа.
inserted
таблицата съхранява копия на засегнатите редове по време на INSERT
и UPDATE
изявления. По време на транзакция за вмъкване или актуализиране, нови редове се добавят и към двата inserted
маса и масата на тригера. Редовете в inserted
таблицата са копия на новите редове в таблицата за задействане.
В допълнение към inserted
таблица, SQL Server също създава и поддържа deleted
маса. Транзакцията за актуализиране е подобна на операция за изтриване, последвана от операция вмъкване; старите редове се копират в deleted
първо таблица, а след това новите редове се копират в таблицата за задействане и в inserted
таблица.
Задействане за колоната „Дата на създаване“
Използване на DEFAULT
Ограничението е удобен начин за създаване на първоначалната стойност, но рискувате някой да може директно да актуализира тази стойност по-късно.
Ако видите това като проблем, можете да промените задействането, за да включи колоната „Дата на създаване“, така че да я нулира до първоначалната й стойност всеки път, когато има актуализация на реда.
Можете да получите оригиналната стойност от deleted
таблица, като се има предвид, че старите редове се копират първо в тази таблица, преди да се извършат каквито и да било актуализации.