sqlite数据库默认时间值“现在”


190

在sqlite数据库中是否可以创建一个带有默认为timestamp列的表DATETIME('now')

像这样:

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

这给出了一个错误...如何解决?

Answers:


290

我相信你可以使用

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

从3.1版开始(来源


22
如果您担心存储大小,请注意,此配方将以ISO-8601(文本格式)保存时间戳,每个日期在数据库中占用约24个字节。您可以通过仅使用INTEGER(4)列并通过“ INSERT INTO test(t)值(strftime(“%s”,CURRENT_TIME));”存储unix时间来节省空间。
mckoss 2012年

3
@mckoss感谢您的评论,create语句变为:... mycolumn默认值(strftime('%s','now'))
larham1 2012年

1
“ ...默认(strftime('%s','now'))”不是常量表达式,如果给出“错误:列[...]的默认值不是恒定值”,则不能与默认值一起使用。
Mirek Rusin'8

@mckoss不错,但是SQLite忽略了“ INTEGER”之后的“(4)”。SQLite文档:数据类型在SQLite版本3中,“括号内的数字参数会被SQLite忽略……类型名称...的后面,并且用于存储” INTEGER”存储类的值的字节数取决于“大小”。价值”。所以,我认为你是正确的,SQLite的将其存储只有4个字节,但在2038年,就不得不使用6个字节,希望电脑可以通过再和在今年4461642. 8个字节编码
ma11hew28 '19

94

据博士。在最近的列表帖子中的hipp:

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

非常感谢!我对的格式不满意,CURRENT_TIMESTAMP因此我在C中创建了自己的函数以返回自大纪元以来的微秒数,我很高兴现在可以使用它DEFAULT
2014年

39

这只是一个语法错误,您需要括号: (DATETIME('now'))

如果您查看文档,则会注意到语法中在'expr'选项周围添加的括号。


18

这是一个完整的示例,它基于对该问题的其他答案和评论。在示例中,时间戳(created_at-column)被保存为unix epoch UTC时区,仅在必要时才转换为本地时区。

使用unix纪元可以节省存储空间-以ISO8601字符串存储时,字符串存储空间为4字节整数,而字符串为24字节,请参见datatypes。如果4个字节不足,则可以增加到6或8个字节。

在UTC时区上保存时间戳可以方便地在多个时区上显示合理的值。

Ubuntu LTS 14.04附带的SQLite版本是3.8.6。

$ 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

由于查询时我位于UTC + 2 DST,所以本地时间是正确的。


7

最好使用REAL类型,以节省存储空间。

引用SQLite版本3数据类型的 1.2部分

SQLite没有为存储日期和/或时间预留存储类。相反,SQLite内置的日期和时间功能可以将日期和时间存储为TEXT,REAL或INTEGER值

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

参见column-constraint

插入一行而不提供任何值。

INSERT INTO "test" DEFAULT VALUES;

1
我更愿意integer(n)选择适合的价值n
user272735

4

这是语法错误,因为您没有写括号

如果你写

选择datetime('now'),它将为您提供utc时间,但如果您对此进行查询,则必须在此之前添加括号,以便为UTC Time加上(datetime('now'))。对于本地时间相同选择datetime('now','localtime')进行查询

(datetime('now','localtime'))


1

此替代示例将本地时间存储为Integer以保存20个字节。该工作在字段default,Update-trigger和View中完成。strftime必须使用“%s”(单引号),因为“%s”(双引号)对我抛出了“ Not Constant”错误。

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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.