158 votes

Comment avoir un horodatage automatique dans SQLite ?

J'ai une base de données SQLite, version 3 et j'utilise C# pour créer une application qui utilise cette base de données.

Je veux utiliser un champ horodateur dans une table pour la concurrence, mais je remarque que lorsque j'insère un nouvel enregistrement, ce champ n'est pas défini et est nul.

Par exemple, dans MS SQL Server, si j'utilise un champ d'horodatage, celui-ci est mis à jour par la base de données, je n'ai pas à le définir moi-même. Est-ce possible dans SQLite ?

245voto

CL. Points 46451

Il suffit de déclarer une valeur par défaut pour un champ :

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

Toutefois, si votre INSERT définit explicitement ce champ à NULL il sera réglé sur NULL .

7 votes

Ce n'est pas tout à fait équivalent à l'horodatage de SQL Server, car il est basé sur l'horloge du système ; si vous changez l'horloge, la valeur pourrait revenir en arrière. Dans SQL Server, les valeurs d'horodatage sont toujours incrémentées.

34 votes

@Matthieu Il n'y a pas DATETIME données mais SQLite accepte n'importe quoi comme champ type.

4 votes

@Matthieu Le type de données DATETIME est mentionné dans SQLite dans le lien que vous avez fourni. Lire 2.2 Exemples de noms d'affinité

74voto

mr.boyfox Points 3704

Vous pouvez créer le champ TIMESTAMP dans la table sur le SQLite, voir ceci :

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

Voici le résultat :

SELECT * FROM my_table;

enter image description here

0 votes

Impossible d'ajouter une colonne avec une valeur par défaut non constante (ALTER TABLE "main". "xxx_data" ADD COLUMN "created_date" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP)

0 votes

TIMESTAMP n'est pas un vrai type dans SQLite. Leur documentation pour l'affinité de type utilise DATETIME.

16voto

centurian Points 131

Lecture datefunc un exemple fonctionnel de la complétion automatique de la date serait :

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

Insérons quelques lignes d'une manière qui déclenche la complétion automatique de la date :

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

Les données enregistrées montrent clairement que les deux premières fonctions sont les mêmes, mais pas la troisième :

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

Faites attention que les fonctions SQLite sont entourées de parenthèses ! C'était difficile de le montrer dans un seul exemple ?

Amusez-vous bien !

9voto

Rahmat Anjirabi Points 101

Vous pouvez utiliser des déclencheurs. cela fonctionne très bien

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;

6voto

Rafael Points 419

Pour compléter les réponses ci-dessus...

Si vous utilisez EF, ajoutez à la propriété l'annotation de données [Timestamp], puis allez à la surcharge OnModelCreating, dans votre classe de contexte, et ajoutez ce code d'API fluide :

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

Il donnera une valeur par défaut à toutes les données qui seront insérées dans cette table.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X