Některé databázové tabulky obsahují sloupec „poslední úprava“, ve kterém je uloženo datum a čas poslední aktualizace řádku. Při každé aktualizaci řádku se datum aktualizuje tak, aby odráželo datum a čas této aktualizace.
V SQL Server můžete tuto aktualizaci provést pomocí spouštěče.
Spouštěč je speciální typ uložené procedury, která se automaticky spustí, když na databázovém serveru dojde k události.
Můžete použít CREATE TRIGGER
příkaz k vytvoření spouštěče při použití T-SQL. Tento příkaz lze použít k vytvoření spouštěče DML, DDL nebo přihlášení.
Příklad
Následující kód vytvoří tabulku a také spouštěč, který aktualizuje ModifiedDate
vždy, když dojde k aktualizaci.
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);
Vložit řádek
Vložíme řádek a vybereme jej, abychom viděli výsledek DEFAULT
omezení:
INSERT INTO Books (BookName)
VALUES ('Trigger Happy');
SELECT * FROM Books;
Výsledek (při použití vertikálního výstupu):
-[ RECORD 1 ]------------------------- BookId | 1 BookName | Trigger Happy CreateDate | 2020-08-17 23:33:15.230 ModifiedDate | 2020-08-17 23:33:15.230
To se zobrazuje pomocí vertikálního výstupu, aby se to usnadnilo čtení (abyste nemuseli posouvat do stran, abyste si přečetli všechny sloupce).
V tomto případě obě CreatedDate
a ModifiedDate
sloupce obsahují stejnou hodnotu. Pokud je však řádek aktualizován, ModifiedDate
hodnota by se měla změnit. Proto jsme vytvořili spouštěč.
Aktualizujte řádek
Nyní aktualizujeme řádek a vybereme výsledky.
UPDATE Books
SET BookName = 'Trigger Hippy'
WHERE BookId = 1;
SELECT * FROM Books;
Výsledek (při použití vertikálního výstupu):
-[ RECORD 1 ]------------------------- BookId | 1 BookName | Trigger Hippy CreateDate | 2020-08-17 23:33:15.230 ModifiedDate | 2020-08-18 00:07:39.680
Podle očekávání ModifiedDate
sloupec je aktualizován, ale CreateDate
sloupec zůstává stejný.
Další vysvětlení kodexu
Níže je podrobnější vysvětlení kódu použitého k vytvoření tabulky a souvisejícího spouštěče.
Tabulka
Následující kód vytvoří tabulku:
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
sloupec má DEFAULT
omezení, které nastaví výchozí hodnotu na CURRENT_TIMESTAMP
(stejně jako CreateDate
sloupec).
To znamená, že při prvním vložení řádku se zobrazí CURRENT_TIMESTAMP
se vloží do těchto sloupců.
To je v pořádku pro počáteční vložení, ale nezabývá se žádnými následnými aktualizacemi. Tady nastává spoušť.
Spouštěč
Následující kód vytvoří spouštěč:
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);
V tomto případě jsem spouštěč nazval trg_Books_UpdateModifiedDate
.
Vytvořil jsem jej na dbo.Books
databáze a spouští se po každém UPDATE
.
Když se spustí, aktualizuje ModifiedDate
sloupec do CURRENT_TIMESTAMP
(ale pouze na řádku, který byl aktualizován, samozřejmě).
Dokážu určit, který řádek byl aktualizován kontrolou inserted
stůl. inserted
table je dočasná tabulka rezidentní v paměti, kterou SQL Server vytváří a spravuje.
inserted
tabulka ukládá kopie dotčených řádků během INSERT
a UPDATE
prohlášení. Během transakce vložení nebo aktualizace se do obou inserted
přidají nové řádky stůl a spouštěcí stůl. Řádky v inserted
table jsou kopie nových řádků v tabulce spouštěčů.
Kromě inserted
SQL Server také vytváří a udržuje deleted
stůl. Aktualizační transakce je podobná operaci odstranění následované operací vložení; staré řádky se zkopírují do deleted
nejprve do tabulky a poté se nové řádky zkopírují do spouštěcí tabulky a do inserted
tabulka.
Spouštěč pro sloupec „Datum vytvoření“
Pomocí DEFAULT
omezení je praktický způsob, jak vytvořit počáteční hodnotu, ale riskujete, že někdo později tuto hodnotu přímo aktualizuje.
Pokud to vidíte jako problém, můžete upravit spouštěč tak, aby zahrnoval sloupec „Datum vytvoření“, takže jej obnoví na původní hodnotu pokaždé, když dojde k aktualizaci řádku.
Původní hodnotu můžete získat z deleted
tabulka, protože staré řádky jsou zkopírovány do této tabulky nejprve, než proběhnou jakékoli aktualizace.