Bagaimana cara mendapatkan cap waktu otomatis dalam SQLite?

132

Saya memiliki database SQLite, versi 3 dan saya menggunakan C # untuk membuat aplikasi yang menggunakan database ini.

Saya ingin menggunakan bidang cap waktu dalam tabel untuk konkurensi, tetapi saya perhatikan bahwa ketika saya memasukkan catatan baru, bidang ini tidak disetel, dan tidak ada.

Sebagai contoh, dalam MS SQL Server jika saya menggunakan bidang cap waktu ini diperbarui oleh database, saya tidak harus mengatur sendiri. apakah ini mungkin dalam SQLite?

Álvaro García
sumber

Jawaban:

212

Cukup nyatakan nilai default untuk bidang:

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

Namun, jika INSERTperintah Anda secara eksplisit menyetel bidang ini ke NULL, ia akan diatur ke NULL.

CL.
sumber
5
Itu tidak cukup setara dengan timestamp SQL Server karena didasarkan pada jam sistem; jika Anda mengubah jam, nilainya bisa mundur. Di SQL Server, nilai timestamp selalu bertambah.
Rory MacLeod
26
@ Matthieu Tidak ada tipe DATETIME data , tetapi SQLite menerima apa pun sebagai tipe bidang .
CL.
4
@ Matthieu Ada DATETIME datatype yang disebutkan dalam SQLite di tautan yang telah Anda berikan. Baca 2.2 Contoh Nama Afinitas
Rafique Mohammed
6
Ini sepertinya tidak mencakup pernyataan UPDATE. Sepertinya pemicu adalah satu-satunya cara untuk melakukan ini.
Dale Anderson
2
@ CL Maaf, Anda benar. Saya salah menggabungkan jawaban Anda dan javed. Dengan DEFAULT (STRFTIME('%Y-%m-%d %H:%M:%f', 'NOW', 'localtime'))satu sebenarnya mendapatkan nilai mikrodetik yang berarti.
Dietmar
71

Anda bisa membuat bidang TIMESTAMP dalam tabel di SQLite, lihat ini:

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

Ini hasilnya:

SELECT * FROM my_table;

masukkan deskripsi gambar di sini

mr.boyfox
sumber
Tidak dapat menambahkan kolom dengan default tidak konstan (ALTER TABLE "main". "Xxx_data" ADD COLUMN "Created_date" TIMESTAMP BUKAN NULL DEFAULT CURRENT_TIMESTAMP)
toing_toing
14

Tanggal membaca berfungsi sebagai contoh kerja penyelesaian data otomatis adalah:

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

Mari kita masukkan beberapa baris dengan cara yang memulai penyelesaian data otomatis:

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

Data yang disimpan dengan jelas menunjukkan bahwa dua yang pertama adalah sama tetapi bukan fungsi yang ketiga:

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

Perhatikan bahwa fungsi SQLite dikelilingi dalam tanda kurung! Seberapa sulitkah ini untuk ditunjukkan dalam satu contoh?

Selamat bersenang-senang!

centurian
sumber
7

Anda bisa menggunakan pemicu. bekerja dengan sangat baik

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;
Rahmat Anjirabi
sumber
6

Untuk melengkapi jawaban di atas ...

Jika Anda menggunakan EF, hiasi properti dengan Data Annotation [Timestamp], lalu buka OnModelCreating yang ditimpa, di dalam kelas konteks Anda, dan tambahkan kode API Lancar ini:

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

Ini akan membuat nilai default untuk setiap data yang akan dimasukkan ke dalam tabel ini.

Rafael
sumber
Tahu kinerja Entity di Android, di aplikasi Xamarin? Belum sempat mencoba, meskipun akan lebih baik untuk mengganti DAL dengan.
samis
Saya tidak menemukan paket yang diperlukan untuk sqliteHasDefault. Anda tahu paket mana yang harus saya dapatkan dari nuget?
Simons0n
@ Simons0n, coba gunakan Microsoft.EntityFrameworkCore.Metadata.Builders.PropertyBuilder namespace ini.
Rafael
2

Anda dapat menggunakan datetime khusus dengan menggunakan ...

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

gunakan 'SEKARANG', 'waktu lokal' untuk mendapatkan tanggal sistem saat ini, jika tidak, ini akan menunjukkan beberapa waktu lampau atau waktu lain dalam Database Anda setelah waktu penyisipan di db Anda.

Terimakasih...

Javed
sumber
1
Berguna jika Anda membutuhkan mikrodetik; Anda dapat menggunakan DEFAULT (STRFTIME ('% Y-% m-% d% H:% M:% f', 'NOW', 'localtime')) `. Hanya dengan mengatakan DEFAULT CURRENT_TIMESTAMP hanya akan memberi Anda rincian satu detik.
Dietmar
Ini pasti berhasil! perhatikan strftime () karena dikelilingi dengan tanda kurung!
centurian
0

Jika Anda menggunakan SQLite DB-Browser Anda dapat mengubah nilai default dengan cara ini:

  1. Pilih struktur basis data
  2. pilih tabel
  3. ubah tabel
  4. di kolom Anda taruh di bawah 'nilai default' nilainya: = (datetime ('now', 'localtime'))

Saya merekomendasikan untuk membuat pembaruan database Anda sebelumnya, karena format yang salah dalam nilai dapat menyebabkan masalah di Browser SQLLite.

SJX
sumber