Como ter um carimbo de data / hora automático no SQLite?

132

Eu tenho um banco de dados SQLite, versão 3 e estou usando C # para criar um aplicativo que usa esse banco de dados.

Desejo usar um campo de carimbo de data / hora em uma tabela para simultaneidade, mas percebo que, quando insiro um novo registro, esse campo não está definido e é nulo.

Por exemplo, no MS SQL Server, se eu usar um campo de carimbo de data e hora, ele será atualizado pelo banco de dados, não preciso definir sozinho. isso é possível no SQLite?

Álvaro García
fonte

Respostas:

212

Apenas declare um valor padrão para um campo:

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

No entanto, se o seu INSERTcomando definir explicitamente esse campo como NULL, ele será definido como NULL.

CL.
fonte
5
Isso não é exatamente equivalente ao registro de data e hora do SQL Server, porque é baseado no relógio do sistema; se você alterar o relógio, o valor poderá retroceder. No SQL Server, os valores de carimbo de data e hora estão sempre aumentando.
Rory MacLeod
26
@ Matthieu Não há tipo de DATETIME dados , mas o SQLite aceita qualquer coisa como tipo de campo .
CL.
4
@ Matthieu Há um tipo de dados DATETIME mencionado no SQLite no link que você forneceu. Leia 2.2 Affinity Nome Exemplos
Rafique Mohammed
6
Parece não cobrir as instruções UPDATE. Parece que um gatilho é a única maneira de fazer isso.
Dale Anderson
2
@CL Desculpe, você está certo. Mesclei incorretamente sua resposta e a de javed. Com DEFAULT (STRFTIME('%Y-%m-%d %H:%M:%f', 'NOW', 'localtime'))um realmente obtém valores significativos de microssegundos.
Dietmar 22/06
71

Você pode criar o campo TIMESTAMP na tabela no SQLite, veja o seguinte:

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 é o resultado:

SELECT * FROM my_table;

insira a descrição da imagem aqui

mr.boyfox
fonte
Não é possível adicionar uma coluna com padrão não constante (ALTER TABLE "main". "Xxx_data" ADD COLUMN "created_date" TIMESTAMP NÃO NULL PADRÃO CURRENT_TIMESTAMP)
toing_toing 27/03/19
14

Lendo datefunc, um exemplo prático de conclusão automática de data e hora seria:

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

Vamos inserir algumas linhas de uma maneira que inicie a conclusão automática de data e hora:

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

Os dados armazenados mostram claramente que os dois primeiros são iguais, mas não a terceira função:

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 atenção que as funções SQLite estão entre parênteses! Quão difícil foi mostrar isso em um exemplo?

Diverta-se!

centuriano
fonte
7

você pode usar gatilhos. funciona muito bem

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
fonte
6

Para complementar as respostas acima ...

Se você estiver usando EF, adorne a propriedade com Data Annotation [Timestamp], vá para o OnModelCreating substituído, dentro da sua classe de contexto, e adicione este código da API Fluent:

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

Ele criará um valor padrão para todos os dados que serão inseridos nesta tabela.

Rafael
fonte
Sabe como o Entity se sai no Android, em um aplicativo Xamarin? Ainda não testei, mas seria bom substituir o DAL por.
Samis 18/0518
Não encontro o pacote necessário para o sqliteHasDefault. Você sabe qual pacote eu tenho que pegar da pepita?
Simons0n
@ Simons0n, tente usar este espaço para nome Microsoft.EntityFrameworkCore.Metadata.Builders.PropertyBuilder.
Rafael
2

você pode usar o datetime personalizado 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 obter a data atual do sistema; caso contrário, ele mostrará algum tempo passado ou outro no seu banco de dados após o tempo de inserção no banco de dados.

Te agradece...

Javed
fonte
1
Útil se você precisar de microssegundos; você pode usar DEFAULT (STRFTIME ('% Y-% m-% d% H:% M:% f', 'AGORA', 'hora local')) ``. Apenas dizer DEFAULT CURRENT_TIMESTAMP fornecerá apenas uma granularidade de um segundo.
Dietmar 22/06
Isso definitivamente funciona! preste atenção ao strftime (), pois está entre parênteses!
centurian 25/09
0

Se você usar o SQLite DB-Browser, poderá alterar o valor padrão desta maneira:

  1. Escolha a estrutura do banco de dados
  2. selecione a tabela
  3. modificar tabela
  4. em sua coluna, coloque em 'valor padrão' o valor: = (datetime ('now', 'localtime'))

Eu recomendo fazer uma atualização do seu banco de dados antes, porque um formato incorreto no valor pode levar a problemas no SQLLite Browser.

SJX
fonte