SQLite 实际上支持 DATE 类型吗?

Posted

技术标签:

【中文标题】SQLite 实际上支持 DATE 类型吗?【英文标题】:Does SQLite actually support DATE type? 【发布时间】:2021-01-06 13:02:15 【问题描述】:

在阅读https://sqlite.org/datatype3.html 后指出

"SQLite 没有专门用于存储日期的存储类 和/或时间。”

但是可以运行这个

CREATE TABLE User (ID INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, BORN_ON DATE NULL)

然后在“DB Browser for SQL”中查看,如下所示:

我开始怀疑 SQLite 是否支持 Date 类型,它只是“伪造”使用其他类型的支持。即使是这样,为什么 DB 浏览器将其视为日期?任何元信息存储在数据库中?

【问题讨论】:

您是否阅读了您链接的文章中的“类型亲和力”部分?你可以为类型添加任何你想要的东西。 【参考方案1】:

SQLite 不会用Numerics 伪造Date

SQLite 中没有 Date 数据类型。

Datatypes In SQLite Version 3 中明确说明:

SQLite 使用更通用的动态类型系统

除了数据类型之外,还有 5 个存储类NULLINTEGERREALTEXTBLOB

还有:

SQLite 版本 3 数据库中的

任何列,INTEGER PRIMARY 除外 KEY 列,可用于存储 any 存储类的值。

因此,当您在CREATE TABLE 语句中使用Date 作为列的数据类型时,您不仅限于在其中存储类似日期的值。实际上,您可以在该列中存储任何内容。

“SQLite 数据库浏览器”等工具和其他工具可能会提供各种数据类型供您在创建表时选择以定义列。 您选择的数据类型没有限制性,而是表明您希望在列中存储什么类型的数据。

其实,你甚至可以不声明列的数据类型来创建表:

CREATE TABLE tablename(col1, col2) 

或使用虚构的数据类型:

CREATE TABLE tablename(col1 somedatatype, col2 otherdatatype)

并插入任何数据类型的值:

INSERT INTO tablename(col1, col2) VALUES 
  (1, 'abc'),
  ('XYZ', '2021-01-06'),
  (null, 3.5)

【讨论】:

【参考方案2】:

根据 Colonel Thirty Two 的建议(在页面上阅读更多内容),当您将字段声明为 Date 时,其关联性似乎是数字。

所以 SQLite 用数字“伪造”日期。

【讨论】:

“所以 SQLite 用数字“伪造”日期。它不会伪造它;它只是没有特别对待它。【参考方案3】:

即使是这样,为什么 DB 浏览器将其视为日期?任何元信息存储在数据库中?

是的,它只是存储创建列时使用的类型名称。链接页面将其称为“声明类型”。在这种情况下,您将获得 NUMERIC 亲和力(DATE 甚至作为 3.1.1 中的示例之一给出)并且它的行为与具有此亲和力的任何其他列一样:

具有 NUMERIC 关联的列可能包含使用所有五个存储类的值。将文本数据插入 NUMERIC 列时,如果文本分别是格式良好的整数或实数文字,则文本的存储类将转换为 INTEGER 或 REAL(按优先顺序)。如果 TEXT 值是格式正确的整数文字,它太大而无法放入 64 位有符号整数,则将其转换为 REAL。对于 TEXT 和 REAL 存储类之间的转换,仅保留数字的前 15 位有效十进制数字。如果 TEXT 值不是格式正确的整数或实数,则该值存储为 TEXT。就本段而言,十六进制整数文字不被视为格式正确,而是存储为 TEXT。 (这样做是为了与版本 3.8.6 2014-08-15 之前的 SQLite 版本保持历史兼容性,其中首次将十六进制整数文字引入 SQLite。)如果可以将可以完全表示为整数的浮点值插入到具有 NUMERIC 亲和性的列,该值将转换为整数。不会尝试转换 NULL 或 BLOB 值。

字符串可能看起来像带有小数点和/或指数表示法的浮点文字,但只要该值可以表示为整数,NUMERIC 亲和性就会将其转换为整数。因此,字符串 '3.0e+5' 存储在具有 NUMERIC 亲和性的列中作为整数 300000,而不是作为浮点值 300000.0。

因此,如果您插入的日期看起来像"2021-01-05" 它们将被存储为字符串。但是

    您还可以插入看起来不像日期的字符串。

    如果您插入"20210105",它将被存储为数字20210105

您可以使用CHECK 约束来防止插入非日期字符串。

另请参阅https://sqlite.org/lang_datefunc.html,它说明日期/时间函数期望什么(字符串和数字)格式。

【讨论】:

以上是关于SQLite 实际上支持 DATE 类型吗?的主要内容,如果未能解决你的问题,请参考以下文章

sqlite数据库如何插入以及修改date类型的字段

SQLite3中如何给日期时间类型数据赋值?

[转]SQLite支持字段类型及建表

sqlite3日期数据类型

Android 使用 sqlcipher 加密数据库

SQLite 3.37.0 发布,支持严格的字段数据类型