Comment avoir un horodatage automatique dans SQLite?

132

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 souhaite utiliser un champ d'horodatage 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 ne dois pas le définir moi-même. est-ce possible dans SQLite?

Álvaro García
la source

Réponses:

212

Déclarez simplement une valeur par défaut pour un champ:

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

Cependant, si votre INSERTcommande définit explicitement ce champ sur NULL, il sera défini sur NULL.

CL.
la source
5
Ce n'est pas tout à fait équivalent à l'horodatage de SQL Server car il est basé sur l'horloge système; si vous modifiez l'horloge, la valeur pourrait reculer. Dans SQL Server, les valeurs d'horodatage sont toujours incrémentées.
Rory MacLeod
26
@Matthieu Il n'y a pas DATETIME de type de données , mais SQLite accepte n'importe quoi comme type de champ .
CL.
4
@Matthieu Il y a un type de données DATETIME mentionné dans SQLite dans le lien que vous avez fourni. Lire 2.2 Exemples de noms d'affinité
Rafique Mohammed
6
Cela ne semble pas couvrir les instructions UPDATE. Il semble qu'un déclencheur soit le seul moyen de le faire.
Dale Anderson
2
@CL Désolé, vous avez raison. J'ai mal fusionné votre réponse et javed's. Avec DEFAULT (STRFTIME('%Y-%m-%d %H:%M:%f', 'NOW', 'localtime'))on obtient en fait des valeurs de microseconde significatives.
Dietmar
71

Vous pouvez créer un 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;

entrez la description de l'image ici

monsieur boyfox
la source
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)
toing_toing
14

La lecture de datefunc un exemple de travail de complétion automatique de date / heure 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 de manière à lancer la complétion automatique de la date / heure:

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

Les données stockées montrent clairement que les deux premiers sont identiques mais pas la troisième fonction:

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

Attention, les fonctions SQLite sont entre parenthèses! Dans quelle mesure était-ce difficile de le montrer dans un exemple?

S'amuser!

centurien
la source
7

vous pouvez utiliser des déclencheurs. 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;
Rahmat Anjirabi
la source
6

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

Si vous utilisez EF, décorez la propriété avec Data Annotation [Timestamp], puis accédez à OnModelCreating surchargé, dans votre classe de contexte, et ajoutez ce code API Fluent:

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

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

Rafael
la source
Savoir comment Entity fonctionne sur Android, dans une application Xamarin? Je n'ai pas eu le temps de tester, mais ce serait bien de remplacer DAL par.
samis
Je ne trouve pas le package nécessaire pour sqliteHasDefault. Vous savez quel paquet je dois obtenir de nuget?
Simons0n
@ Simons0n, essayez d'utiliser cet espace de noms Microsoft.EntityFrameworkCore.Metadata.Builders.PropertyBuilder.
Rafael
2

vous pouvez utiliser le datetime personnalisé en utilisant ...

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

utilisez «NOW», «localtime» pour obtenir la date actuelle du système, sinon il affichera une heure passée ou autre dans votre base de données après l'heure d'insertion dans votre base de données.

Merci...

Javed
la source
1
Utile si vous avez besoin de microsecondes; vous pouvez utiliser DEFAULT (STRFTIME ('% Y-% m-% d% H:% M:% f', 'NOW', 'localtime')) `. Dire simplement DEFAULT CURRENT_TIMESTAMP ne vous donnera qu'une granularité d'une seconde.
Dietmar
Cela fonctionne vraiment! faites attention à strftime () car il est entouré de parenthèses!
centurian
0

Si vous utilisez SQLite DB-Browser, vous pouvez modifier la valeur par défaut de cette manière:

  1. Choisissez la structure de la base de données
  2. sélectionnez la table
  3. modifier la table
  4. dans votre colonne, mettez sous 'valeur par défaut' la valeur: = (datetime ('now', 'localtime'))

Je recommande de faire une mise à jour de votre base de données avant, car un format incorrect dans la valeur peut entraîner des problèmes dans le navigateur SQLLite.

SJX
la source