Timestamp v MSSQL

MSSQL sice obsahuje datový typ „timestamp“, který je aktualizován při každé změně záznamu. Problém je ale v tom, že nemá žádný vztah k datumu a času. Jde o číslo v binárním formátu.
Pokud tedy chceme zjistit čas, kdy došlo ke změně záznamu, musíme použít trigger, který bude nastavovat hodnotu do pole typu „datetime“.

Spustíme MS SQL Server Manager Studio.
Předpokládáme, že máme v databázi tabulku „users“ a v ni sloupec „mtime“ typu „datetime“.
Pole „mtime“ bude obsahovat timestamp.
Jako defaultni hodnotu nastavime „getDate()“. Tím zajistíme, že nově vložený záznam bude mít v poli „mtime“ aktuální čas.
Teď už zbývá pouze zajistit, aby se aktuální čas nastavil i v případě, že budeme záznam modifikovat.
K tomu nám poslouží trigger na událost update.
Ten vytvoříte tak, že v kontextovém menu vybereme možnost „New Trigger…“. Viz obrázek.

Jak vytvořit nový trigger

Otevře se okno, kam napíšeme samotný kód.
Ten by mohl vypadat nějak takto:

CREATE TRIGGER tr_UserTimestamp
   ON  users
   FOR UPDATE
AS 
BEGIN
    DECLARE changedRecords Cursor
    FOR
    SELECT d.id FROM Deleted d, Inserted i
    WHERE d.id = i.idz
    AND (d.firstName <> i.firstName OR d.lastName <> i.lastName)
    
    DECLARE @recordId CHAR(12)
    
    OPEN changedRecords
    FETCH NEXT FROM changedRecords INTO @recordId
    WHILE (@@FETCH_STATUS = 0)
    BEGIN
        UPDATE users
        SET mtime=getDate()
        WHERE id=@recordId
        
        FETCH NEXT FROM changedRecords INTO @recordId
    END
    
    CLOSE changedRecords
    DEALLOCATE changedRecords
END

Tím se říká, aby se vytvořil trigger s názvem „tr_UserTimestamp“ spoustěný při updatu tabulky „users“. V logických tabulkách „Inserted“ a „Deleted“ jsou záznamy, na kterých byl proveden update. V tabulce „Deleted“ jsou staré hodnoty, kdežto v „Inserted“ jsou hodnoty po provedeni update. Zrada je ale v tom, že pokud provedeme update na záznam, během něhož nastavite atributu hodnotu stejnou, jako měl před tím, tak se i tento záznam v tabulkách objeví. Proto jsou v uvedeném kódu porovnávány hodnoty odpovídajicích atributů a záznam je vybrán, pouze pokud se liší. Jen taková malá odbočka – existuje funkce Update() s názvem atributu jako parametr, která vrátí true, pokud byl atribut updetován. Což znamená, že vrátí true vždy, když se vyskytne atribut v UPDATE příkazu bez ohledu na to, jestli se hodnota změní, nebo ne.
Vybrané záznamy jsou po té procházeny pomocí kurzoru, přičemž je nastavován jejich atribut mtime na aktuální čas.

Až máme kód napsány, můžeme kliknout na „Execute“ a tím vytvoříme samotný trigger.