valore ora predefinito del database sqlite 'ora'
Domanda
È possibile in un database sqlite eseguire il craete di una tabella che ha una colonna timestamp che ha come impostazione predefinita DATETIME ('now')
?
In questo modo:
CREATE TABLE test (
id INTEGER PRIMARY KEY AUTOINCREMENT,
t TIMESTAMP DEFAULT DATETIME('now')
);
Questo dà un errore ... Come risolvere?
Soluzione
credo che tu possa usare
CREATE TABLE test (
id INTEGER PRIMARY KEY AUTOINCREMENT,
t TIMESTAMP
DEFAULT CURRENT_TIMESTAMP
);
dalla versione 3.1 ( source )
Altri suggerimenti
secondo il dott. ipp in un recente post dell'elenco:
CREATE TABLE whatever(
....
timestamp DATE DEFAULT (datetime('now','localtime')),
...
);
È solo un errore di sintassi, hai bisogno di parentesi: (DATETIME('now'))
Se guardi la documentazione , noterai tra parentesi che viene aggiunto intorno all'opzione "expr" nella sintassi.
Questo è un esempio completo basato sulle altre risposte e commenti alla domanda. Nell'esempio il timestamp ( Created_at
-column) viene salvato come unix epoch Fuso orario UTC e convertito in fuso orario locale solo quando necessario.
L'uso di unix epoch consente di risparmiare spazio di archiviazione - 4 byte interi contro 24 byte stringa se archiviati come stringa ISO8601, vedere tipi di dati . Se 4 byte non sono sufficienti, è possibile aumentarli a 6 o 8 byte.
Il salvataggio del timestamp sul fuso orario UTC rende conveniente mostrare un valore ragionevole su più fusi orari.
La versione di SQLite è la 3.8.6 fornita con Ubuntu LTS 14.04.
$ sqlite3 so.db
SQLite version 3.8.6 2014-08-15 11:46:33
Enter ".help" for usage hints.
sqlite> .headers on
create table if not exists example (
id integer primary key autoincrement
,data text not null unique
,created_at integer(4) not null default (strftime('%s','now'))
);
insert into example(data) values
('foo')
,('bar')
;
select
id
,data
,created_at as epoch
,datetime(created_at, 'unixepoch') as utc
,datetime(created_at, 'unixepoch', 'localtime') as localtime
from example
order by id
;
id|data|epoch |utc |localtime
1 |foo |1412097842|2014-09-30 17:24:02|2014-09-30 20:24:02
2 |bar |1412097842|2014-09-30 17:24:02|2014-09-30 20:24:02
Localtime è corretto in quanto mi trovo all'ora legale UTC + 2 al momento della query.
Potrebbe essere meglio usare il tipo REAL, per risparmiare spazio di archiviazione.
Citazione dalla sezione 1.2 della Tipi di dati nella versione 3 di SQLite
SQLite non ha una classe di archiviazione riservata per la memorizzazione delle date e / o tempi. Invece, le funzioni integrate di data e ora di SQLite sono in grado di memorizzare date e orari come TEXT, REAL o INTEGER I valori
CREATE TABLE test (
id INTEGER PRIMARY KEY AUTOINCREMENT,
t REAL DEFAULT (datetime('now', 'localtime'))
);
vedi vincolo di colonna .
E inserisci una riga senza fornire alcun valore.
INSERT INTO "test" DEFAULT VALUES;
È un errore di sintassi perché non hai scritto parentesi
se scrivi
Seleziona datetime ('now') allora ti darà il tempo utc ma se scrivi questa query, allora devi aggiungere parentesi prima di questo so (datetime ('now')) per l'ora UTC. per l'ora locale stessa Seleziona datetime ('now', 'localtime') per query
(datetime ( 'società', 'localtime'))
Questo esempio alternativo memorizza l'ora locale come numero intero per salvare i 20 byte. Il lavoro viene svolto nel campo predefinito, Aggiorna-trigger e Visualizza. strftime deve usare '% s' (virgolette singole) perché "% s " (virgolette doppie) ha generato un errore "Non costante" su di me.
Create Table Demo (
idDemo Integer Not Null Primary Key AutoIncrement
,DemoValue Text Not Null Unique
,DatTimIns Integer(4) Not Null Default (strftime('%s', DateTime('Now', 'localtime'))) -- get Now/UTC, convert to local, convert to string/Unix Time, store as Integer(4)
,DatTimUpd Integer(4) Null
);
Create Trigger trgDemoUpd After Update On Demo Begin
Update Demo Set
DatTimUpd = strftime('%s', DateTime('Now', 'localtime')) -- same as DatTimIns
Where idDemo = new.idDemo;
End;
Create View If Not Exists vewDemo As Select -- convert Unix-Times to DateTimes so not every single query needs to do so
idDemo
,DemoValue
,DateTime(DatTimIns, 'unixepoch') As DatTimIns -- convert Integer(4) (treating it as Unix-Time)
,DateTime(DatTimUpd, 'unixepoch') As DatTimUpd -- to YYYY-MM-DD HH:MM:SS
From Demo;
Insert Into Demo (DemoValue) Values ('One'); -- activate the field Default
-- WAIT a few seconds --
Insert Into Demo (DemoValue) Values ('Two'); -- same thing but with
Insert Into Demo (DemoValue) Values ('Thr'); -- later time values
Update Demo Set DemoValue = DemoValue || ' Upd' Where idDemo = 1; -- activate the Update-trigger
Select * From Demo; -- display raw audit values
idDemo DemoValue DatTimIns DatTimUpd
------ --------- ---------- ----------
1 One Upd 1560024902 1560024944
2 Two 1560024944
3 Thr 1560024944
Select * From vewDemo; -- display automatic audit values
idDemo DemoValue DatTimIns DatTimUpd
------ --------- ------------------- -------------------
1 One Upd 2019-06-08 20:15:02 2019-06-08 20:15:44
2 Two 2019-06-08 20:15:44
3 Thr 2019-06-08 20:15:44