SQLite'da otomatik zaman damgası nasıl olur?


132

Bir SQLite veritabanım var, sürüm 3 ve bu veritabanını kullanan bir uygulama oluşturmak için C # kullanıyorum.

Eşzamanlılık için bir tabloda bir zaman damgası alanı kullanmak istiyorum, ancak yeni bir kayıt eklediğimde bu alanın ayarlanmadığını ve boş olduğunu fark ettim.

Örneğin, MS SQL Server'da bir zaman damgası alanı kullanırsam, bu veri tabanı tarafından güncellenir, kendim ayarlamam gerekmez. bu SQLite'de mümkün mü?

Yanıtlar:


212

Bir alan için varsayılan bir değer belirtmeniz yeterlidir:

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

Ancak, INSERTkomutunuz açıkça bu alanı NULLolarak ayarlarsa, olarak ayarlanacaktır NULL.


5
Bu, sistem saatine dayandığı için SQL Server'ın zaman damgasına tam olarak denk değildir; saati değiştirirseniz, değer geriye gidebilir. SQL Server'da, zaman damgası değerleri her zaman artmaktadır.
Rory MacLeod

26
@Matthieu DATETIME Veri türü yoktur , ancak SQLite herhangi bir şeyi alan türü olarak kabul eder .
CL.

4
@Matthieu Sağladığınız bağlantıda SQLite'da belirtilen DATETIME veri türü var. 2.2 Yakın İlgi
Alanı

6
Bu, UPDATE ifadelerini kapsamıyor gibi görünüyor. Bunu yapmanın tek yolu tetik gibi görünüyor.
Dale Anderson

2
@CL Üzgünüm, haklısınız. Cevabınızı yanlış bir şekilde birleştirdim. DEFAULT (STRFTIME('%Y-%m-%d %H:%M:%f', 'NOW', 'localtime'))Biri ile anlamlı mikrosaniye değerleri elde edilir.
Dietmar

71

SQLite üzerindeki tabloda TIMESTAMP alanı oluşturabilirsiniz, şuna bakın:

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');

Sonuç şu:

SELECT * FROM my_table;

görüntü açıklamasını buraya girin


Sabit olmayan varsayılana sahip bir sütun eklenemez (ALTER TABLE "main". "Xxx_data" COLUMN EKLE "created_date" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP)
toing_toing

14

Datefunc okunması , otomatik tarih-saat tamamlamanın çalışan bir örneği şöyle olacaktır:

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'))
   ...> );

Otomatik tarih saat tamamlamayı başlatacak şekilde birkaç satır ekleyelim:

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

Depolanan veriler, ilk ikisinin aynı olduğunu ancak üçüncü işlev olmadığını açıkça göstermektedir:

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

SQLite işlevlerinin parantez içine alındığına dikkat edin! Bunu bir örnekte göstermek ne kadar zordu?

İyi eğlenceler!


7

tetikleyicileri kullanabilirsiniz. çok iyi çalışıyor

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

Yukarıdaki cevapları tamamlamak için ...

EF kullanıyorsanız, özelliği Data Annotation [Timestamp] ile süsleyin, ardından bağlam sınıfınızın içindeki geçersiz kılınan OnModelCreating'e gidin ve bu Fluent API kodunu ekleyin:

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

Bu tabloya eklenecek her veriye varsayılan bir değer verecektir.


Entity'nin bir Xamarin uygulamasında Android'de nasıl performans gösterdiğini biliyor musunuz? Teste henüz gelmedim, ancak DAL'ı ile değiştirmek güzel olurdu.
samis

SqliteHasDefault için gerekli olan paketi bulamıyorum. Nuget'ten hangi paketi almam gerektiğini biliyor musun?
Simons0n

@ Simons0n, bu Microsoft.EntityFrameworkCore.Metadata.Builders.PropertyBuilder ad alanını kullanmayı deneyin.
Rafael

2

özel tarih saatini kullanarak ...

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

Geçerli sistem tarihini almak için 'ŞİMDİ', 'localtime' kullanın, aksi takdirde veritabanınıza ekleme süresinden sonra Veritabanınızda geçmiş veya başka bir zaman gösterecektir.

Teşekkürler...


1
Mikrosaniye ihtiyacınız varsa kullanışlıdır; VARSAYILAN (STRFTIME ('% Y-% m-% d% H:% M:% f', 'NOW', 'localtime')) kullanabilirsiniz. Sadece DEFAULT CURRENT_TIMESTAMP demek size yalnızca bir saniyelik bir ayrıntı düzeyi verecektir.
Dietmar

Bu kesinlikle işe yarıyor! parantez içinde olduğu gibi strftime () 'ye dikkat edin!
centurian

0

SQLite DB-Browser kullanıyorsanız, varsayılan değeri şu şekilde değiştirebilirsiniz:

  1. Veritabanı yapısını seçin
  2. masayı seç
  3. tabloyu değiştir
  4. sütununuzda 'varsayılan değer' altına değeri koyun: = (tarihsaat ('şimdi', 'yerel zaman'))

Değerdeki yanlış bir format SQLLite Browser'da sorunlara yol açabileceğinden, veritabanınızı önceden güncellemenizi tavsiye ederim.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.