理解 SQLite 中的日期时间和数据类型
Making sense of date-time and datatypes in SQLite
我目前正在学习 SQL 和 SQLite,据我所知,SQLite 不支持 datetime
数据类型。
但是,当我 运行 命令 PRAGMA table_info(Orders);
时,它显示一列的类型为 datetime
。
我读过 In SQLite, the datatype of a value is associated with the value itself, not with its container.
摘自此处 https://www.sqlite.org/datatype3.html
我正在尝试理解这到底是什么意思,这可能有助于解释。
有人可以帮助我了解这里发生了什么吗?
执行时在type
列中看到的内容:
PRAGMA table_info(tablename)
或:
SELECT * FROM pragma_table_info('tablename');
是用于在 CREATE TABLE
语句中定义列的数据类型。
SQLite 允许使用任何(甚至没有)作为数据类型,只要它不是保留字。
这个:
CREATE TABLE tablename (
column0 integer primary key,
column1 integer,
column2 text,
column3 real,
column4 string,
column5 something,
column6 Jack,
column7, -- no data type defined
column8 real char int -- ??,
column9 datetime
);
是一个有效的声明!
根据以上所有列定义,SQLite 将仅对定义为 integer primary key
.
的列 column0
强制执行类型检查
来自 Datatypes In SQLite Version 3/Storage Classes and Datatypes:
Any column in an SQLite version 3 database, except an INTEGER PRIMARY
KEY column, may be used to store a value of any storage class.
当您将列定义为 datetime
时,不要指望 SQLite 理解您的意图并设置任何内部约束,以便您存储在其中的值类似于日期时间。
实际上,根据 Determination Of Column Affinity 中描述的规则,此列将具有 NUMERIC
亲和力。
当然,您可以使用 INTEGER
、REAL
或 TEXT
数据类型将日期时间值存储在列中,如 Date and Time Datatype 中所述,具体取决于您想要的日期时间形式:分别为 Unix Time
s、Julian day numbers
或 ISO8601 strings ("YYYY-MM-DD HH:MM:SS.SSS")
字符串。
总之,SQLite 永远不会抱怨定义为任何数据类型的任何列中的任何值(integer primary key
除外)。
您有责任确保以正确的格式存储值,以便您可以 read/write、进行计算、比较等
例如,切勿以 "YYYY-MM-DD HH:MM:SS.SSS"
以外的任何其他格式存储文本日期时间,因为所有 SQLite's datetime functions 仅适用于此格式。
为了扩大@ 的出色答案,您可以通过在 table 定义中使用 CHECK
约束来弥补 SQLite 的弱类型检查。我经常这样做是为了强制使用整数或字符串长度,您可以使用 SQLite 的日期函数来验证该值是否可以解析为日期并位于两个值之间。
我目前正在学习 SQL 和 SQLite,据我所知,SQLite 不支持 datetime
数据类型。
但是,当我 运行 命令 PRAGMA table_info(Orders);
时,它显示一列的类型为 datetime
。
我读过 In SQLite, the datatype of a value is associated with the value itself, not with its container.
摘自此处 https://www.sqlite.org/datatype3.html
我正在尝试理解这到底是什么意思,这可能有助于解释。
有人可以帮助我了解这里发生了什么吗?
执行时在type
列中看到的内容:
PRAGMA table_info(tablename)
或:
SELECT * FROM pragma_table_info('tablename');
是用于在 CREATE TABLE
语句中定义列的数据类型。
SQLite 允许使用任何(甚至没有)作为数据类型,只要它不是保留字。
这个:
CREATE TABLE tablename (
column0 integer primary key,
column1 integer,
column2 text,
column3 real,
column4 string,
column5 something,
column6 Jack,
column7, -- no data type defined
column8 real char int -- ??,
column9 datetime
);
是一个有效的声明!
根据以上所有列定义,SQLite 将仅对定义为 integer primary key
.
column0
强制执行类型检查
来自 Datatypes In SQLite Version 3/Storage Classes and Datatypes:
Any column in an SQLite version 3 database, except an INTEGER PRIMARY KEY column, may be used to store a value of any storage class.
当您将列定义为 datetime
时,不要指望 SQLite 理解您的意图并设置任何内部约束,以便您存储在其中的值类似于日期时间。
实际上,根据 Determination Of Column Affinity 中描述的规则,此列将具有 NUMERIC
亲和力。
当然,您可以使用 INTEGER
、REAL
或 TEXT
数据类型将日期时间值存储在列中,如 Date and Time Datatype 中所述,具体取决于您想要的日期时间形式:分别为 Unix Time
s、Julian day numbers
或 ISO8601 strings ("YYYY-MM-DD HH:MM:SS.SSS")
字符串。
总之,SQLite 永远不会抱怨定义为任何数据类型的任何列中的任何值(integer primary key
除外)。
您有责任确保以正确的格式存储值,以便您可以 read/write、进行计算、比较等
例如,切勿以 "YYYY-MM-DD HH:MM:SS.SSS"
以外的任何其他格式存储文本日期时间,因为所有 SQLite's datetime functions 仅适用于此格式。
为了扩大@CHECK
约束来弥补 SQLite 的弱类型检查。我经常这样做是为了强制使用整数或字符串长度,您可以使用 SQLite 的日期函数来验证该值是否可以解析为日期并位于两个值之间。