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

本文涉及的产品
RDS MySQL DuckDB 分析主实例,集群系列 4核8GB
RDS AI 助手,专业版
简介: 在本文中,作者分享了如何使用sqlite3数据库来记录结构化日志,并实现主键ID自增、插入数据时自动填充创建时间(created_at)以及更新数据时更新时间(updated_at)的功能。首先,创建数据库和表`position_info`,然后通过修改表结构使ID字段为自动递增。接着,设置`created_at`和`updated_at`字段默认值为当前时间。最后,创建一个触发器在数据更新时自动更新`updated_at`。完整SQL代码包括表创建和触发器定义。

最近在记录一些简单的结构化日志信息时,用到了sqlite3数据库(保存的信息比较简单,用MysqlSQL ServerPostgres这些数据库有点小题大做)。

以前开发系统时,用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

相关文章
|
存储 数据安全/隐私保护
Rockchip系列之VendorStorage 浅浅的介绍(1)
Rockchip系列之VendorStorage 浅浅的介绍(1)
971 0
|
JSON 应用服务中间件 nginx
如何修改kong网关access.log的日志格式
有需要需要调整kong网关的日志格式,调整日志输出内容,由于原来使用docker部署kong网关,并且使用了环境变量指定了网关运行的参数,这里在以下介绍的方式还需要修改容器的环境变量,但是也提供了一条思路,就是部署网关的时候,统一使用kong.conf进行配置
1400 0
|
程序员 C++
智能指针避坑指南——几种常见的错误用法
智能指针避坑指南——几种常见的错误用法
|
8月前
|
运维 Ubuntu Linux
Linux重置root用户密码
本文详细介绍了Linux系统中root密码重置的核心技能,涵盖主流发行版如RHEL、CentOS、Debian、Ubuntu、Arch、openSUSE等的实操方法。内容包括通过GRUB引导编辑、单用户模式和Live CD救援三种方式重置密码的具体步骤,适配物理机、虚拟机及云服务器环境。文章分步解析了启动拦截、权限获取和密码重置三大阶段,并提供各发行版的实际操作代码示例,帮助管理员快速解决忘记root密码的问题。
|
Linux 网络安全 Python
linux centos上安装python3.11.x详细完整教程
这篇文章提供了在CentOS系统上安装Python 3.11.x版本的详细步骤,包括下载、解压、安装依赖、编译配置、解决常见错误以及版本验证。
11005 3
linux centos上安装python3.11.x详细完整教程
|
7月前
|
安全 Java 数据库
使用Java实现用户的注册和登录流程
以上提供了用户注册和登录的基本框架和必要的说明。在具体的应用场景中,可能还需结合框架特性如Spring Security等提供的高级特性来实现更为完备和安全的用户认证机制。在开发期间,务必注重代码的安全性、清晰性和可维护性,为用户资料保驾护航。
498 13
|
定位技术
wgs84和wgs84web如何转换?
wgs84和wgs84web如何转换?
1420 60
|
JavaScript
cnpm 的安装与使用
本文介绍了npm和cnpm的概念、安装nodejs的步骤,以及cnpm的安装和使用方法,提供了通过配置npm使用中国镜像源来加速包下载的替代方案,并说明了如何恢复npm默认仓库地址。
cnpm 的安装与使用
|
数据安全/隐私保护 Windows
限制访问网站、过滤特定网址、禁止访问指定网站的方法
许多公司出于管理员工上网行为的需要,经常限制电脑访问一些网站例如游戏网站、购物网站或是视频网站等等
1232 3
|
SQL JavaScript 数据库
sqlite在Windows环境下安装、使用、node.js连接
sqlite在Windows环境下安装、使用、node.js连接