Witaj na Zine.net online Zaloguj się | Rejestracja | Pomoc

[PL] Stempel czasowy czy mit ponadczasowy?

W związku z powtarzającymi się pytaniami o to, jak zrzutować dane typu TIMESTAMP na typy daty i czasu i robić inne “cuda, wianki” związane z tym typem (pytania widziałem zarówno na forum WSS.pl, jak i na forum MSDN, jak i na Experts-Exchange.com), postanowiłem napisać tę notkę. A więc po kolei:

  1. Typ TIMESTAMP zaimplementowany w SQL Server nie ma nic wspólnego z datą i czasem. Został tak nieszczęśliwie nazwany przez programistów MS, ale nie jest to typ daty i czasu ze standardu SQL-92 o tej samej nazwie. A więc, sorry folks, ale rzutowanie TIMESTAMP na DATETIME jest raczej bez sensu (chyba, że chcecie zobaczyć, która wartość jest większa, bo faktycznie ciężko to może być zweryfikować patrząc na binaria) :-)
  2. Niestety, nazwa pewnej funkcji systemowej – CURRENT_TIMESTAMP – powoduje jeszcze większe zamieszanie. Ta funkcja ma jak najbardziej związek z datą i czasem – zwraca wartość typu DATETIME (CURRENT_TIMESTAMP to synonim dla GETDATE w SQL Server). Tu MS jest zgodny ze standardem SQL-92. Cóż za (nie)konsekwencja, rzekłbym :-)
  3. Bardziej szczęśliwą nazwą dla typu TIMESTAMP jest ROWVERSION (obu nazw można używać zamiennie). MS twierdzi, że TIMESTAMP ma być "deprecated" i że należy używać właśnie ROWVERSION. Nazwa ROWVERSION lepiej oddaje podstawowe zastosowanie tego typu danych, czyli wersjonowanie wierszy (stara wersja kolumny ROWVERSION może zostać skopiowana do kolumny typu BINARY). Oczywistym zastosowaniem jest też kontrola kolejności, w jakiej rekordy w tabeli lub w całej bazie danych były dodawane lub modyfikowane.
  4. W SQL Server typ ROWVERSION (odzwyczajajmy się od TIMESTAMP) jest typem binarnym.

    CREATE TABLE #temp (
      ID int,
      Stamp rowversion
    )
    
    INSERT #temp (ID) SELECT 1
    
    SELECT Stamp FROM #temp

    Wyniki zapytania mogą się różnić, ale będzie to coś na kształt:
     

    Stamp
    ------------------
    0x00000000000007D1

  5. Kolumny typu ROWVERSION mają służyć do przechowywania informacji o tym, w jakiej kolejności rekordy w konkretnej bazie danych (a w dalszej kolejności – w konkretnej tabeli) były wstawiane/modyfikowane.
  6. MS gwarantuje unikalność dla wszystkich wartości typu ROWVERSION na poziomie pojedynczej bazy danych.
  7. Może być tylko jedna kolumna typu ROWVERSION w tabeli.
  8. Tak, jak do kolumn wyliczanych, nie można wstawiać "rękoma" danych do kolumn typu ROWVERSION (SQL Server sam wstawia odpowiednie wartości).
  9. Jeśli wstawisz wiersze do tabeli z kolumną typu ROWVERSION, a następnie usuniesz je i wstawisz nowe wiersze, wartości ROWVERSION będą różne (większe) od wartości, jakie były wstawione na usuniętych wierszy.
  10. Możesz użyć funkcji @@DBTS do zwrócenia wartości, która jako ostatnia została wstawiona do jakiejkolwiek kolumny typu ROWVERSION w bieżącej bazie danych.

I na koniec ciekawostka, a nawet dwie. Można stworzyć kolumnę typu TIMESTAMP (celowo nie ROWVERSION, o czym za chwilę) nie podając jej nazwy:

CREATE TABLE dbo.Test (
    ID int,
    timestamp
)

Kolumna automatycznie zostanie nazwama [timestamp]. Nie ma możliwości utworzenia tabeli w ten sposób wykorzystując ROWVERSION (może to i dobrze, wolę jawnie nazywać kolumny w tabelach).

I druga ciekawostka – o ile MS twierdzi, że TIMESTAMP jest "deprecated", o tyle jeśli zajrzeć do widoku sys.types na SQL Server 2005 i 2008, typ TIMESTAMP tam jest, a ROWVERSION nie...

A może masz swoje doświadczenia z TIMESTAMP/ROWVERSION i chcesz się nimi podzielić? Śmiało – czekam na komentarze lub maile.

Opublikowane 22 sierpnia 2008 10:43 przez brejk

Komentarze:

# re: [PL] Stempel czasowy czy mit ponadczasowy?

22 sierpnia 2008 11:08 by dario-g

Brakuje chyba tylko jeszcze (w sumie oczywistego) opisu zastosowania danych typu timest... (sorki) rowversion :) (jako uzupełnienie notki :))

# re: [PL] Stempel czasowy czy mit ponadczasowy?

22 sierpnia 2008 11:20 by Wojciech Gebczyk

Pawel,

Jak dlubalem cos-kiedys w okolicach SQL 2005/SQL CE 3.5/3.1, to byl jakis problem z posiadaniem 2 kolumn TS/RV. Nie pamietam dokladnie, ale trzeba bylo zalozyc kolumne binarna ktora by trzymala dane.

Czy to prawda? Czy mozna miec wiecej niz jedna kolumne RV? Bo jesli tylko jedna to wyglada tak slabo jak z mySQL'em gdzie (przynajmniej jakis czas temu) tak bywalo.

A scenarousz uzycia to posiadanie tabeli z "historia" (dosc ogolnie mowiac) i przechowywanie czasu modyfikacji wierszy - SyncFramework jak by sie ktos pytal szczegolowej.

To jak? Napsiszesz cos o tym?

# re: [PL] Stempel czasowy czy mit ponadczasowy?

22 sierpnia 2008 12:08 by brejk

Dzięki Panowie. Dodałem informację o tym, że może być jedna kolumna typu ROWVERSION w tabeli oraz informację o podstawowych zastosowaniach.

# re: [PL] Stempel czasowy czy mit ponadczasowy?

1 października 2008 22:43 by WiNi

A jak mapujecie typ ROWVERSION na SqlDbType w .NET?

1)

SqlParameter param = cmd.Parameters.Add("@RowV", SqlDbType.Binary, 8, "RowV");

czy

2)

SqlParameter param = cmd.Parameters.Add("@RowV", SqlDbType.Timestamp, 8, "RowV");

Pozdrawiam

Wiesiek

Komentarze anonimowe wyłączone

About brejk

MVP, MCT, SQL Server geek