Come avere un timestamp automatico in SQLite?


132

Ho un database SQLite, versione 3 e sto usando C # per creare un'applicazione che utilizza questo database.

Voglio utilizzare un campo data / ora in una tabella per la concorrenza, ma noto che quando inserisco un nuovo record, questo campo non è impostato ed è nullo.

Ad esempio, in MS SQL Server se utilizzo un campo timestamp che viene aggiornato dal database, non devo impostarlo da solo. è possibile in SQLite?

Risposte:


212

Dichiara semplicemente un valore predefinito per un campo:

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

Tuttavia, se il INSERTcomando imposta esplicitamente questo campo su NULL, verrà impostato su NULL.


5
Questo non è del tutto equivalente al timestamp di SQL Server perché si basa sull'orologio di sistema; se si cambia l'orologio, il valore potrebbe tornare indietro. In SQL Server, i valori di data e ora aumentano sempre.
Rory MacLeod,

26
@Matthieu Non esiste un tipo di DATETIME dati , ma SQLite accetta qualsiasi cosa come tipo di campo .
CL.

4
@Matthieu Esiste un tipo di dati DATETIME menzionato in SQLite nel collegamento fornito. Leggi 2.2 Esempi di nomi di affinità
Rafique Mohammed,

6
Questo non sembra coprire le dichiarazioni UPDATE. Sembra che un trigger sia l'unico modo per farlo.
Dale Anderson,

2
@CL Mi dispiace, hai ragione. Ho erroneamente unito la tua risposta e quella di javed. Con DEFAULT (STRFTIME('%Y-%m-%d %H:%M:%f', 'NOW', 'localtime'))uno effettivamente si ottengono valori significativi di microsecondi.
Dietmar,

71

È possibile creare il campo TIMESTAMP nella tabella su SQLite, vedere questo:

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

Questo è il risultato:

SELECT * FROM my_table;

inserisci qui la descrizione dell'immagine


Impossibile aggiungere una colonna con valore predefinito non costante (ALTER TABLE "main". "Xxx_data" ADD COLUMN "Created_date" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP)
toing_toing

14

La lettura di datefunc un esempio funzionante di completamento automatico del datetime sarebbe:

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

Inseriamo alcune righe in modo da avviare il completamento automatico del datetime:

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

I dati memorizzati mostrano chiaramente che i primi due sono uguali ma non la terza funzione:

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

Fai attenzione che le funzioni SQLite siano racchiuse tra parentesi! Quanto è stato difficile mostrarlo in un esempio?

Divertiti!


7

puoi usare i trigger. funziona molto bene

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

Per integrare le risposte sopra ...

Se si utilizza EF, adornare la proprietà con Data Annotation [Timestamp], quindi andare a OnModelCreating sovrascritto, all'interno della classe di contesto e aggiungere questo codice API fluente:

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

Farà un valore predefinito per tutti i dati che verranno inseriti in questa tabella.


Sai come si comporta Entity su Android, in un'app Xamarin? Non sono andato in giro per i test, anche se sarebbe bello sostituire il DAL.
Samis,

Non trovo il pacchetto necessario per sqliteHasDefault. Sai quale pacchetto devo ottenere da Nuget?
Simons0n

@ Simons0n, prova a utilizzare questo spazio dei nomi Microsoft.EntityFrameworkCore.Metadata.Builders.PropertyBuilder.
Rafael,

2

puoi usare il datetime personalizzato usando ...

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

usa 'NOW', 'localtime' per ottenere la data di sistema corrente altrimenti mostrerà qualche ora passata o altra nel tuo Database dopo l'ora di inserimento nel tuo db.

Grazie...


1
Utile se hai bisogno di microsecondi; puoi usare DEFAULT (STRFTIME ('% Y-% m-% d% H:% M:% f', 'NOW', 'localtime')) `. Solo dicendo DEFAULT CURRENT_TIMESTAMP ti darà solo una granularità di un secondo.
Dietmar,

Questo sicuramente funziona! presta attenzione a strftime () come è racchiuso tra parentesi!
centuriano,

0

Se si utilizza il browser DB SQLite è possibile modificare il valore predefinito in questo modo:

  1. Scegli la struttura del database
  2. seleziona la tabella
  3. modifica tabella
  4. nella colonna inserisci sotto "valore predefinito" il valore: = (datetime ('now', 'localtime'))

Consiglio di effettuare un aggiornamento del database prima, poiché un formato errato nel valore può causare problemi nel browser SQLLite.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.