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

sqlite数据库默认时间值“现在”,sql,sqlite,Sql,Sqlite,在sqlite数据库中,是否可以创建一个具有默认为DATETIME“now”的时间戳列的表 像这样: CREATE TABLE test ( id INTEGER PRIMARY KEY AUTOINCREMENT, t TIMESTAMP DEFAULT DATETIME('now') ); 这给出了一个错误。。。如何解决?我相信您可以使用 CREATE TABLE test ( id INTEGER PRIMARY KEY AUTOINCREMENT, t TIM

在sqlite数据库中,是否可以创建一个具有默认为DATETIME“now”的时间戳列的表

像这样:

CREATE TABLE test (
    id INTEGER PRIMARY KEY AUTOINCREMENT, 
    t TIMESTAMP DEFAULT DATETIME('now')
);
这给出了一个错误。。。如何解决?

我相信您可以使用

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

从3.1版开始,根据hipp博士在最近的一篇列表帖子:

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

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


如果查看,您会注意到在语法中围绕“expr”选项添加的括号。

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

如果你写信

选择datetime'now' 然后它将给您utc时间,但如果您编写此查询,则必须在此之前添加括号 因此,UTC时间的日期时间为“现在”。 当地时间相同 选择datetime'now'、'localtime' 查询


datetime'now','localtime'

为了节省存储空间,最好使用REAL类型

引自第1.2节

SQLite没有为存储日期而预留的存储类 和/或时间。相反,SQLite的内置日期和时间函数 能够将日期和时间存储为文本、实数或整数 价值观

和一行,但不提供任何值

INSERT INTO "test" DEFAULT VALUES;

这是一个基于对该问题的其他回答和评论的完整示例。在本例中,创建的时间戳_at列保存为UTC时区,并仅在必要时转换为本地时区

使用unix epoch可节省存储空间—当存储为ISO8601字符串时,整数为4字节,字符串为24字节,请参阅。如果4个字节不够,可以增加到6或8个字节

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

SQLite版本是Ubuntu LTS 14.04附带的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

Localtime是正确的,因为在查询时我位于UTC+2 DST。

此替代示例将本地时间存储为整数,以保存20个字节。工作在字段default、updatetrigger和View中完成。 strftime必须使用“%s”单引号,因为%s双引号在我身上引发了“非常量”错误

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

如果需要毫秒精度,请尝试以下操作:

CREATE TABLE my_table (
    timestamp DATETIME DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now'))
);

不过,这会将时间戳保存为文本。

如果您关心存储大小,请注意,此配方会将时间戳保存为ISO-8601文本格式,每个日期在数据库中占用大约24字节。只需使用INTEGER4列,并通过将unix时间插入测试t值strftime%s,CURRENT_time@谢谢你的评论,create语句变成了:。。。mycolumn默认strftime“%s”,“now”。。。默认strftime“%s”,“now”不是常量表达式,无法使用默认给定错误:列[…]的默认值不是常量。@mckoss nice,但SQLite会忽略整数后面的4。在类型名称后面的括号中表示数字参数。被SQLite忽略,用于存储INTEGER存储类值的字节数取决于值的大小。所以,我认为你是对的,SQLite将只存储4个字节,但到2038年,它将不得不使用6个字节,希望到那时计算机可以编码,到4461642年将使用8个字节。非常感谢!我对当前_时间戳的格式不满意,所以我用C创建了自己的函数来返回自纪元以来的微秒数,我很高兴现在可以使用它作为默认值。我更喜欢整数,在这里可以为n选择合适的值。
CREATE TABLE my_table (
    timestamp DATETIME DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now'))
);