Jak mieć automatyczny znacznik czasu w SQLite?


139

Mam bazę danych SQLite w wersji 3 i używam języka C # do tworzenia aplikacji korzystającej z tej bazy danych.

Chcę użyć pola datownika w tabeli do współbieżności, ale zauważam, że kiedy wstawiam nowy rekord, to pole nie jest ustawione i ma wartość null.

Na przykład w MS SQL Server, jeśli używam pola znacznika czasu, jest ono aktualizowane przez bazę danych, nie muszę ustawiać samodzielnie. czy to możliwe w SQLite?

Odpowiedzi:


220

Po prostu zadeklaruj domyślną wartość pola:

CREATE TABLE MyTable(
    ID INTEGER PRIMARY KEY,
    Name TEXT,
    Other STUFF,
    Timestamp DATETIME DEFAULT CURRENT_TIMESTAMP
);

Jeśli jednak twoja INSERTkomenda jawnie ustawia to pole na NULL, zostanie ustawione na NULL.


6
Nie jest to odpowiednik sygnatury czasowej programu SQL Server, ponieważ jest oparty na zegarze systemowym; jeśli zmienisz zegar, wartość może się cofnąć. W SQL Server wartości sygnatur czasowych są zawsze zwiększane.
Rory MacLeod

27
@Matthieu Nie ma typu DATETIME danych , ale SQLite akceptuje wszystko jako typ pola .
CL.

4
@Matthieu Istnieje typ danych DATETIME wymieniony w SQLite w podanym linku. Przeczytaj 2.2 Przykłady nazw
koligacji

7
Wydaje się, że to nie obejmuje instrukcji UPDATE. Wygląda na to, że jedynym sposobem na to jest wyzwalacz.
Dale Anderson

2
@CL Przepraszamy, masz rację. Błędnie połączyłem twoją odpowiedź i javed. Z DEFAULT (STRFTIME('%Y-%m-%d %H:%M:%f', 'NOW', 'localtime'))jednym faktycznie uzyskuje się znaczące wartości w mikrosekundach.
Dietmar

72

Możesz utworzyć pole TIMESTAMP w tabeli na SQLite, zobacz:

CREATE TABLE my_table (
    id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
    name VARCHAR(64),
    sqltime TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL
);

INSERT INTO my_table(name, sqltime) VALUES('test1', '2010-05-28T15:36:56.200');
INSERT INTO my_table(name, sqltime) VALUES('test2', '2010-08-28T13:40:02.200');
INSERT INTO my_table(name) VALUES('test3');

Oto wynik:

SELECT * FROM my_table;

wprowadź opis obrazu tutaj


Nie można dodać kolumny z niestałą wartością domyślną (ALTER TABLE "main". "Xxx_data" ADD COLUMN "created_date" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP)
toing_toing

15

Czytając datefunc, działającym przykładem automatycznego uzupełniania daty i godziny byłby:

sqlite> CREATE TABLE 'test' ( 
   ...>    'id' INTEGER PRIMARY KEY,
   ...>    'dt1' DATETIME NOT NULL DEFAULT (datetime(CURRENT_TIMESTAMP, 'localtime')), 
   ...>    'dt2' DATETIME NOT NULL DEFAULT (strftime('%Y-%m-%d %H:%M:%S', 'now', 'localtime')), 
   ...>    'dt3' DATETIME NOT NULL DEFAULT (strftime('%Y-%m-%d %H:%M:%f', 'now', 'localtime'))
   ...> );

Wstawmy kilka wierszy w sposób, który zainicjuje automatyczne uzupełnianie daty i godziny:

sqlite> INSERT INTO 'test' ('id') VALUES (null);
sqlite> INSERT INTO 'test' ('id') VALUES (null);

Zapisane dane wyraźnie pokazują, że pierwsze dwie są takie same, ale nie trzecia funkcja:

sqlite> SELECT * FROM 'test';
1|2017-09-26 09:10:08|2017-09-26 09:10:08|2017-09-26 09:10:08.053
2|2017-09-26 09:10:56|2017-09-26 09:10:56|2017-09-26 09:10:56.894

Zwróć uwagę, że funkcje SQLite są ujęte w nawiasy! Jak trudno było to pokazać na jednym przykładzie?

Baw się dobrze!


7

możesz użyć wyzwalaczy. działa bardzo dobrze

CREATE TABLE MyTable(
ID INTEGER PRIMARY KEY,
Name TEXT,
Other STUFF,
Timestamp DATETIME);


CREATE TRIGGER insert_Timestamp_Trigger
AFTER INSERT ON MyTable
BEGIN
   UPDATE MyTable SET Timestamp =STRFTIME('%Y-%m-%d %H:%M:%f', 'NOW') WHERE id = NEW.id;
END;

CREATE TRIGGER update_Timestamp_Trigger
AFTER UPDATE On MyTable
BEGIN
   UPDATE MyTable SET Timestamp = STRFTIME('%Y-%m-%d %H:%M:%f', 'NOW') WHERE id = NEW.id;
END;

6

Aby uzupełnić powyższe odpowiedzi ...

Jeśli używasz EF, udekoruj właściwość adnotacją danych [Timestamp], a następnie przejdź do nadpisanego OnModelCreating, wewnątrz klasy kontekstu i dodaj ten kod interfejsu API Fluent:

modelBuilder.Entity<YourEntity>()
                .Property(b => b.Timestamp)
                .ValueGeneratedOnAddOrUpdate()
                .IsConcurrencyToken()
                .ForSqliteHasDefaultValueSql("CURRENT_TIMESTAMP");

Spowoduje to ustawienie wartości domyślnej dla wszystkich danych, które zostaną wstawione do tej tabeli.


Wiesz, jak Entity działa na Androidzie w aplikacji Xamarin? Nie zabrałem się za testowanie, chociaż byłoby miło zastąpić DAL.
samis

Nie mogę znaleźć pakietu, który jest wymagany dla sqliteHasDefault. Wiesz, jaką paczkę mam dostać od Nuget?
Simons0n

@ Simons0n, spróbuj użyć tej przestrzeni nazw Microsoft.EntityFrameworkCore.Metadata.Builders.PropertyBuilder.
Rafael

3

możesz użyć niestandardowej daty i godziny, używając ...

 create table noteTable3 
 (created_at DATETIME DEFAULT (STRFTIME('%d-%m-%Y   %H:%M', 'NOW','localtime')),
 title text not null, myNotes text not null);

użyj „TERAZ”, „czas lokalny”, aby uzyskać bieżącą datę systemową, w przeciwnym razie pokaże ona przeszłość lub inny czas w Twojej bazie danych po czasie wstawienia do bazy danych.

Dzięki Ci...


2
Przydatne, jeśli potrzebujesz mikrosekund; możesz użyć DEFAULT (STRFTIME ('% Y-% m-% d% H:% M:% f', 'NOW', 'localtime')) `. Samo powiedzenie DEFAULT CURRENT_TIMESTAMP da Ci dokładność tylko do jednej sekundy.
Dietmar

To zdecydowanie działa! zwróć uwagę na strftime (), które jest otoczone nawiasami!
centurian

0

Jeśli używasz SQLite DB-Browser, możesz zmienić domyślną wartość w następujący sposób:

  1. Wybierz strukturę bazy danych
  2. wybierz tabelę
  3. zmodyfikuj tabelę
  4. w kolumnie umieść pod „wartością domyślną” wartość: = (datetime („now”, „localtime”))

Zalecam wcześniej aktualizację bazy danych, ponieważ niewłaściwy format wartości może prowadzić do problemów w przeglądarce SQLLite.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.