¿Cómo tener una marca de tiempo automática en SQLite?


132

Tengo una base de datos SQLite, versión 3 y estoy usando C # para crear una aplicación que use esta base de datos.

Quiero usar un campo de marca de tiempo en una tabla para concurrencia, pero noto que cuando inserto un nuevo registro, este campo no está configurado y es nulo.

Por ejemplo, en MS SQL Server, si uso un campo de marca de tiempo, esto es actualizado por la base de datos, no tengo que configurarlo yo mismo. ¿Es esto posible en SQLite?

Respuestas:


212

Simplemente declare un valor predeterminado para un campo:

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

Sin embargo, si su INSERTcomando establece explícitamente este campo en NULL, se establecerá en NULL.


55
Eso no es equivalente a la marca de tiempo de SQL Server porque se basa en el reloj del sistema; Si cambia el reloj, el valor podría ir hacia atrás. En SQL Server, los valores de la marca de tiempo siempre se incrementan.
Rory MacLeod

26
@ Matthieu No hay tipo de DATETIME datos , pero SQLite acepta cualquier cosa como tipo de campo .
CL.

44
@Matthieu Hay un tipo de datos DATETIME mencionado en SQLite en el enlace que ha proporcionado. Lea 2.2 Ejemplos de nombres de afinidad
Rafique Mohammed

66
Esto no parece cubrir las declaraciones de ACTUALIZACIÓN. Parece que un disparador es la única forma de hacer esto.
Dale Anderson

2
@CL Lo siento, tienes razón. Fusioné incorrectamente tu respuesta y la de Javed. Con DEFAULT (STRFTIME('%Y-%m-%d %H:%M:%f', 'NOW', 'localtime'))uno realmente se obtienen valores significativos de microsegundos.
Dietmar

71

Puede crear el campo TIMESTAMP en la tabla en el SQLite, vea esto:

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

Este es el resultado:

SELECT * FROM my_table;

ingrese la descripción de la imagen aquí


No se puede agregar una columna con valor predeterminado no constante (ALTER TABLE "main". "Xxx_data" ADD COLUMN "created_date" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP)
toing_toing

14

Al leer datefunc, un ejemplo práctico de finalización automática de fecha y hora sería:

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

Insertemos algunas filas de una manera que inicie la finalización automática de fecha y hora:

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

Los datos almacenados muestran claramente que los dos primeros son iguales pero no la tercera función:

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

¡Preste atención a que las funciones SQLite están entre paréntesis! ¿Qué tan difícil fue mostrarlo en un ejemplo?

¡Que te diviertas!


7

Puedes usar disparadores. funciona muy 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;

6

Para complementar las respuestas anteriores ...

Si está utilizando EF, adornar la propiedad con Anotación de datos [Marca de tiempo], luego vaya a OnModelCreating anulado, dentro de su clase de contexto, y agregue este código Fluent API:

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

Hará un valor predeterminado para cada dato que se insertará en esta tabla.


¿Sabe cómo funciona Entity en Android, en una aplicación Xamarin? No he podido probar, aunque sería bueno reemplazar a DAL.
samis

No encuentro el paquete que se necesita para sqliteHasDefault. ¿Sabes qué paquete tengo que obtener de Nuget?
Simons0n

@ Simons0n, intente utilizar este espacio de nombres Microsoft.EntityFrameworkCore.Metadata.Builders.PropertyBuilder.
Rafael

2

puede usar la fecha y hora personalizada usando ...

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

use 'NOW', 'localtime' para obtener la fecha actual del sistema; de lo contrario, mostrará algún tiempo pasado u otro en su base de datos después del tiempo de inserción en su base de datos.

Gracias...


1
Útil si necesita microsegundos; puede usar DEFAULT (STRFTIME ('% Y-% m-% d% H:% M:% f', 'NOW', 'localtime')) `. Solo decir DEFAULT CURRENT_TIMESTAMP solo te dará una granularidad de un segundo.
Dietmar

¡Esto definitivamente funciona! ¡preste atención a strftime () ya que está rodeado de paréntesis!
Centurian

0

Si utiliza el navegador SQLite DB, puede cambiar el valor predeterminado de esta manera:

  1. Elegir estructura de base de datos
  2. selecciona la mesa
  3. modificar tabla
  4. en su columna coloque bajo 'valor predeterminado' el valor: = (datetime ('now', 'localtime'))

Recomiendo hacer una actualización de su base de datos antes, porque un formato incorrecto en el valor puede causar problemas en el navegador SQLLite.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.