sqlite veritabanı varsayılan zaman değeri 'now'


190

Bir sqlite veritabanında varsayılan olarak zaman damgası sütunu olan bir tablo oluşturmak mümkün DATETIME('now')mü?

Bunun gibi:

CREATE TABLE test (
    id INTEGER PRIMARY KEY AUTOINCREMENT, 
    t TIMESTAMP DEFAULT DATETIME('now')
);

Bu bir hata veriyor ... Nasıl çözülür?

Yanıtlar:


291

kullanabileceğine inanıyorum

CREATE TABLE test (
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  t TIMESTAMP
  DEFAULT CURRENT_TIMESTAMP
);

3.1 sürümünden itibaren ( kaynak )


22
Depolama boyutuyla ilgili endişeleriniz varsa, bu tarifin zaman damgalarınızı ISO-8601 (metin biçimi) biçiminde kaydederek tarihte yaklaşık 24 bayt alan kaplayacağını unutmayın. Yalnızca INTEGER (4) sütununu kullanarak ve "INSERT INTO test (t) değerleri (strftime ("% s ", CURRENT_TIME));"
mckoss

3
@mckoss Yorumunuz sayesinde, create deyimi şu şekilde oldu: ... mycolumn default (strftime ('% s', 'now'))
larham1

1
"... default (strftime ('% s', 'now'))" sabit ifade değil, "Hata: [...] sütununun varsayılan değeri sabit değil" vererek varsayılan olarak çalışmaz.
Mirek Rusin

@mckoss nice, ancak SQLite "INTEGER" den sonra "(4)" değerini yok sayar. SQLite Belgeleri: Veri Türleri SQLite Sürüm 3'te "parantez içindeki tür adını izleyen sayısal değişkenler. SQLite tarafından yoksayılır" ve "INTEGER" depolama sınıfının bir değerini depolamak için kullanılan bayt sayısının büyüklüğüne bağlı olduğunu söyler değeri ". Bu yüzden, SQLite'nin sadece 4 bayt ile depolayacağını düşünüyorum, ancak 2038 yılına kadar 6 bayt kullanmak zorunda kalacak
ma11hew28

94

dr. son liste gönderisinde hipp:

CREATE TABLE whatever(
     ....
     timestamp DATE DEFAULT (datetime('now','localtime')),
     ...
);

Çok teşekkür ederim! CURRENT_TIMESTAMPEpoch'tan bu yana mikrosaniye sayısını döndürmek için C'de kendi işlevimi oluşturduğumdan memnun kalmadım ve bunu bir DEFAULTşimdi olarak kullanabileceğim için mutluyum .
Michael

39

Bu sadece bir sözdizimi hatası, parantez gerekiyor: (DATETIME('now'))

Belgelere bakarsanız , sözdizimindeki 'ifade' seçeneğinin etrafına eklenen parantezi not edersiniz.


18

Bu, sorunun diğer cevaplarına ve yorumlarına dayanan tam bir örnektir. Örnekte, zaman damgası ( created_at-column) unix epoch UTC saat dilimi olarak kaydedilir ve yalnızca gerektiğinde yerel saat dilimine dönüştürülür.

Unix epoch kullanımı, ISO8601 dizesi olarak saklandığında 4 bayt tamsayı ile 24 bayt dizesi depolama alanı kazandırır, bkz . Veri türleri . 4 bayt yeterli değilse, 6 veya 8 bayta çıkarılabilir.

UTC saat diliminde zaman damgası kaydetmek, birden fazla saat diliminde makul bir değer göstermeyi kolaylaştırır.

Ubuntu LTS 14.04 ile birlikte gelen SQLite sürümü 3.8.6'dır.

$ 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, sorgu anında UTC + 2 DST konumunda olduğum için doğrudur.


7

Depolama alanından tasarruf etmek için REAL tipini kullanmak daha iyi olabilir.

SQLite Sürüm 3 Veri Tipleri 1.2 bölümünden alıntı

SQLite, tarihleri ​​ve / veya saatleri saklamak için bir depolama sınıfına sahip değildir. Bunun yerine, SQLite'ın yerleşik Tarih ve Saat İşlevleri, tarihleri ​​ve saatleri METİN, GERÇEK veya INTEGER değerleri olarak saklayabilir

CREATE TABLE test (
    id INTEGER PRIMARY KEY AUTOINCREMENT, 
    t REAL DEFAULT (datetime('now', 'localtime'))
);

bkz. sütun kısıtı .

Ve herhangi bir değer sağlamadan bir satır ekleyin .

INSERT INTO "test" DEFAULT VALUES;

1
integer(n)Birinin uygun değeri nereden seçebileceğini tercih ederim n.
user272735

4

Sözdizimi hatası çünkü parantez yazmadınız

yazarsan

Tarih saatini ('şimdi') seçin, sonra size utc zamanı verecektir, ancak bu yazma sorgusunu yazarsanız, UTC Saati için bundan önce parantez eklemelisiniz (datetime ('now')). aynı yerel saat için sorgu için datetime ('now', 'localtime') seçin

(Tarihi (şimdi ', 'localtime'))


1

Bu alternatif örnek, 20 baytı kaydetmek için yerel saati Tamsayı olarak saklar. İş varsayılan, Güncelle-tetikle ve Görüntüle alanında yapılır. strftime '% s' (tek tırnak) kullanmalıdır çünkü "% s" (çift tırnak) üzerime "Sabit Değil" hatası verdi.

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
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.