sqlite数据库默认时间值'now'

Joe*_*oep 178 sql sqlite

是否可以在sqlite数据库中创建一个具有默认值的时间戳列的表DATETIME('now')

像这样:

CREATE TABLE test (
    id INTEGER PRIMARY KEY AUTOINCREMENT, 
    t TIMESTAMP DEFAULT DATETIME('now')
);
Run Code Online (Sandbox Code Playgroud)

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

Owe*_*wen 271

我相信你可以使用

CREATE TABLE test (
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  t TIMESTAMP
  DEFAULT CURRENT_TIMESTAMP
);
Run Code Online (Sandbox Code Playgroud)

从版本3.1()

  • 如果您担心存储大小,请注意此配方将以ISO-8601(文本格式)保存时间戳,每个日期在数据库中占用大约24个字节.您可以通过使用INTEGER(4)列来节省空间,并通过"INSERT INTO test(t)值(strftime("%s",CURRENT_TIME))存储unix时间;" (21认同)
  • @mckoss感谢您的评论,create语句变为:... mycolumn default(strftime('%s','now')) (3认同)
  • “... default (strftime('%s','now'))”不是常量表达式,不适用于默认给出“错误:列 [...] 的默认值不是常量”。 (2认同)
  • @mckoss 很好,但是 SQLite 忽略“INTEGER”后面的“(4)”。[SQLite 文档:SQLite 版本 3 中的数据类型](https://www.sqlite.org/draft/datatype3.html) 说“类型名称后面的括号中的数字参数...将被 SQLite 忽略”,并且数字用于存储“INTEGER”存储类的值的字节数取决于“值的大小”。所以,我认为你是对的,SQLite 只会用 4 个字节来存储它,但到 2038 年,它必须使用 6 个字节(希望那时计算机可以编码),到 4461642 年则必须使用 8 个字节。 (2认同)

rev*_*rev 89

据博士说.hipp在最近的一个帖子中:

CREATE TABLE whatever(
     ....
     timestamp DATE DEFAULT (datetime('now','localtime')),
     ...
);
Run Code Online (Sandbox Code Playgroud)

  • 有“本地时间”的原因吗?您将服务器/计算机/烤面包机移至太东或太西,然后 kaboom 就会删除您的代码。 (6认同)

Ada*_*ter 36

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

如果查看文档,您将注意到语法中"expr"选项周围添加的括号.


use*_*735 14

这是基于对问题的其他答案和评论的完整示例.在示例中,时间戳(created_at-column)保存为unix epoch 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
Run Code Online (Sandbox Code Playgroud)

本地时间是正确的,因为我在查询时位于UTC + 2 DST.


Nia*_*ang 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'))
);
Run Code Online (Sandbox Code Playgroud)

请参阅列约束.

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

INSERT INTO "test" DEFAULT VALUES;
Run Code Online (Sandbox Code Playgroud)


Jim*_*ker 6

如果你想要毫秒精度,试试这个:

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

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


小智 5

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

如果你写

选择 datetime('now') 然后它会给你 UTC 时间,但是如果你写它查询,那么你必须在这之前添加括号,所以 (datetime('now')) UTC 时间。对于本地时间相同选择 datetime('now','localtime') 进行查询

(日期时间('现在','本地时间'))