sqlite3自动插入创建时间和更新时间

本文涉及的产品
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云原生数据库 PolarDB PostgreSQL 版,标准版 2核4GB 50GB
简介: 在本文中,作者分享了如何在SQLite3中实现类似MySQL和Postgres的几个基本功能。首先,通过`AUTOINCREMENT`关键字设置了主键ID自增。接着,通过`DEFAULT (DATETIME('now', 'localtime'))`确保了`created_at`在数据插入时自动获取当前时间。然而,`updated_at`在数据更新时不自动更新,为解决这个问题,作者创建了一个触发器(`trigger_position_info_updated_at`),在更新数据后自动更新`updated_at`字段。

以前开发系统时,用MysqlPostgres比较多,sqlite3接触不多,

这次使用,希望sqlite3也能提供几个基本的功能,比如:

  1. 主键ID自增
  2. 插入数据时,自动更新创建时间created_at
  3. 更新数据时,自动更新更新时间updated_at

调查这几个功能的过程记录如下。

1. 准备

首先创建一个数据库,sqlite3数据库其实就是一个文件。

powershell

复制代码

$  sqlite3.exe test.db
SQLite version 3.41.2 2023-03-22 11:56:21
Enter ".help" for usage hints.
sqlite>

这里不需要管 test.db 文件存不存在,如果不存在,会自动创建的。

创建一张表 position_info,这是我用来记录账户净值和利润的表,其中字段的作用不用管,

只需要关注 idcreated_atupdated_at三个字段即可。

powershell

复制代码

sqlite> CREATE TABLE IF NOT EXISTS position_info (
(x1...>     id INTEGER NOT NULL PRIMARY KEY,
(x1...>     equity REAL NOT NULL,
(x1...>     profit_loss REAL NOT NULL,
(x1...>     created_at TEXT NOT NULL,
(x1...>     updated_at TEXT NOT NULL
(x1...> );

创建之后,通过sqlite3的命令查看position_info表是否创建。

powershell

复制代码

sqlite> .tables
position_info

sqlite3的自带命令都是以点号.)开头的。

表按照默认的方式创建之后, 发现插入一条数据很麻烦,

需要指定position_info表中所有5个字段才能插入成功。

powershell

复制代码

sqlite> INSERT INTO position_info(id, equity,
(x1...>  profit_loss, created_at, updated_at)
   ...>  VALUES(1, 10, 2,
(x1...>   "2024-06-09 10:10:10", "2024-06-09 10:10:10");

sqlite> .headers on

sqlite> SELECT * FROM position_info;
id|equity|profit_loss|created_at|updated_at
1|10.0|2.0|2024-06-09 10:10:10|2024-06-09 10:10:10

其实,我希望实现的是插入和更新时,只关注equityprofit_loss两个字段,其他3个字段由数据库自动管理。

类似:INSERT INTO position_info(equity, profit_loss) VALUES(10, 2);

下面开始改造。

2. 主键ID自增

首先,让主键ID能够自动增长。

powershell

复制代码

sqlite> drop table position_info;
sqlite> CREATE TABLE IF NOT EXISTS position_info (
(x1...>     id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
(x1...>         equity REAL NOT NULL,
(x1...>         profit_loss REAL NOT NULL,
(x1...>     created_at TEXT NOT NULL,
(x1...>     updated_at TEXT NOT NULL
(x1...> );
sqlite> select * from position_info;
sqlite>

先删除创建的 position_info,然后重新创建position_info表,

创建时指定id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT

创建完成后,插入两条数据,插入时不指定ID字段,发现数据库会帮我们自动插入ID。

powershell

复制代码

sqlite> INSERT INTO position_info(equity,
(x1...>  profit_loss, created_at, updated_at)
   ...>  VALUES(10, 2,
(x1...>   "2024-06-09 10:10:10", "2024-06-09 10:10:10");

sqlite> INSERT INTO position_info(equity,
(x1...>  profit_loss, created_at, updated_at)
   ...>  VALUES(100, 20,
(x1...>   "2024-06-09 11:11:11", "2024-06-09 11:11:11");

sqlite> select * from position_info;
id|equity|profit_loss|created_at|updated_at
1|10.0|2.0|2024-06-09 10:10:10|2024-06-09 10:10:10
2|100.0|20.0|2024-06-09 11:11:11|2024-06-09 11:11:11

3. 创建时间(created_at)

接下来,设置创建时间created_at)和更新时间updated_at)自动插入:DEFAULT (DATETIME('now', 'localtime'))

powershell

复制代码

sqlite> drop table position_info;
sqlite> CREATE TABLE IF NOT EXISTS position_info (
(x1...>     id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
(x1...>         equity REAL NOT NULL,
(x1...>         profit_loss REAL NOT NULL,
(x1...>     created_at TEXT NOT NULL DEFAULT (DATETIME('now', 'localtime')),
(x1...>     updated_at TEXT NOT NULL DEFAULT (DATETIME('now', 'localtime'))
(x1...> );

然后插入两条测试数据:

powershell

复制代码

sqlite> INSERT INTO position_info(equity, profit_loss)
   ...>  VALUES(10, 2);
sqlite>
sqlite> INSERT INTO position_info(equity, profit_loss)
   ...>  VALUES(100, 20);

sqlite> select * from position_info;
id|equity|profit_loss|created_at|updated_at
1|10.0|2.0|2024-06-09 16:40:52|2024-06-09 16:40:52
2|100.0|20.0|2024-06-09 16:40:53|2024-06-09 16:40:53

现在,我们只要关注equityprofit_loss就可以了。

4. 更新时间(updated_at)

经过上面的改造之后,插入数据没有问题了,但是更新数据时还有一个瑕疵。

更新数据时,updated_at字段没有变化,一直是插入数据时的那个时间。

更新前:

powershell

复制代码

sqlite> select * from position_info;
id|equity|profit_loss|created_at|updated_at
1|10.0|2.0|2024-06-09 16:40:52|2024-06-09 16:40:52
2|100.0|20.0|2024-06-09 16:40:53|2024-06-09 16:40:53

更新第一条数据:

powershell

复制代码

sqlite> UPDATE position_info SET equity=500, profit_loss=100
   ...> WHERE id = 1;
sqlite> select * from position_info;
id|equity|profit_loss|created_at|updated_at
1|500.0|100.0|2024-06-09 16:40:52|2024-06-09 16:40:52
2|100.0|20.0|2024-06-09 16:40:53|2024-06-09 16:40:53

第一条数据的equityprofit_loss虽然更新成功了,但是它的updated_at没有更新,还是插入时的2024-06-09 16:40:52

为了让updated_at也能自动更新,需要加一个监听器,当数据有更新时,更新此数据的updated_at字段。

powershell

复制代码

sqlite> CREATE TRIGGER IF NOT EXISTS trigger_position_info_updated_at AFTER UPDATE ON position_info
   ...> BEGIN
   ...>     UPDATE position_info SET updated_at = DATETIME('now', 'localtime') WHERE rowid == NEW.rowid;
   ...> END;

再更新一次数据看看:

powershell

复制代码

sqlite> UPDATE position_info SET equity=1000, profit_loss=300
   ...> WHERE id = 1;
   
sqlite> select * from position_info;
id|equity|profit_loss|created_at|updated_at
1|1000.0|300.0|2024-06-09 16:40:52|2024-06-09 16:49:28
2|100.0|20.0|2024-06-09 16:40:53|2024-06-09 16:40:53

更新数据时,updated_at也更新了,变成2024-06-09 16:49:28,与created_at不再一样。

5. 总结

最后,创建一个带有自增ID,自动插入创建时间更新时间的完整SQL如下:

powershell

复制代码

CREATE TABLE IF NOT EXISTS position_info (
    id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
    equity REAL NOT NULL,
    profit_loss REAL NOT NULL,
    created_at TEXT NOT NULL DEFAULT (DATETIME('now', 'localtime')),
    updated_at TEXT NOT NULL DEFAULT (DATETIME('now', 'localtime'))
);

CREATE TRIGGER IF NOT EXISTS trigger_position_info_updated_at AFTER UPDATE ON position_info
BEGIN
    UPDATE position_info SET updated_at = DATETIME('now', 'localtime') WHERE rowid == NEW.rowid;
END;


转载来源:https://juejin.cn/post/7377697380215341093

相关文章
|
SQL 关系型数据库 MySQL
sqlite3自动插入创建时间和更新时间
在本文中,作者分享了如何使用sqlite3数据库来记录结构化日志,并实现主键ID自增、插入数据时自动填充创建时间(created_at)以及更新数据时更新时间(updated_at)的功能。首先,创建数据库和表`position_info`,然后通过修改表结构使ID字段为自动递增。接着,设置`created_at`和`updated_at`字段默认值为当前时间。最后,创建一个触发器在数据更新时自动更新`updated_at`。完整SQL代码包括表创建和触发器定义。
490 0
|
存储 安全 网络安全
Windows安全防护:构建多层防御体系,守护系统安全
Windows系统的安全性对于保护用户个人信息和企业业务连续运行至关重要。面对日益严峻的网络威胁,我们需要构建多层防御体系,通过采用系统内置的安全防护措施、用户可采取的安全保护措施以及加强用户教育与培训、实施严格的访问控制策略、定期进行系统安全评估与审计、建立应急响应机制以及采用先进的安全防护技术等方式
1042 57
|
Linux 测试技术 Apache
国产 OpenEuler 向 CentOS 发起挑战:这场替代之战结局如何?
【10月更文挑战第3天】在服务器操作系统领域,CentOS 曾是首选,但因项目策略变化,寻找替代品变得迫切。本文将探讨国产开源操作系统 OpenEuler 是否能完美替代 CentOS。OpenEuler 具有强大的性能和稳定性,由国内社区推动,提供出色的安全性和及时更新。其包管理工具与 CentOS 类似,便于上手。
397 3
|
JSON API 开发者
GET方式请求速卖通平台API 接口:商品列表数据获取指南
速卖通商品列表数据接口(如 `aliexpress.item_search`)让开发者获取商品信息列表, 包括名称、价格等关键数据。接口支持按关键词、分类ID等条件获取商品列表及详细信息, 并可通过分页与排序优化展示效果。开发者需在速卖通开放平台注册并创建应用获取API密钥, 构建HTTP请求并处理JSON响应数据。[体验API](http://b.mrw.so/2Pv6Qu)。
|
数据采集 存储 缓存
Rust中的数据抓取:代理和scraper的协同工作
Rust中的数据抓取:代理和scraper的协同工作
|
存储 Linux C++
【C++】Vector -- 详解(上)
【C++】Vector -- 详解(上)
|
存储 JSON 编解码
python之simplejson:JSON 编/解码器示例详解
python之simplejson:JSON 编/解码器示例详解
270 0
|
SQL 存储 关系型数据库
【MySQL】DDL的表操作详解:创建&查询&修改&删除
【MySQL】DDL的表操作详解:创建&查询&修改&删除
|
Java Python Windows
Python pip 源设置成国内源,阿里云源,清华大学源,最方便的方式,都在这里了
Python pip 源设置成国内源,阿里云源,清华大学源,最方便的方式,都在这里了
79214 1
下一篇
oss云网关配置