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

sqlite3 · 浏览次数 : 0

小编点评

本文介绍了如何使用 SQLite3 数据库记录简单的结构化日志信息。文章首先创建了一个名为 "test.db" 的数据库,并在其中创建了一张名为 "position_info" 的表,用于记录账户净值和利润。接着,文章展示了如何让主键 ID 自增、创建时间和更新时间自动更新等功能的实现过程。 1. **创建数据库和表**: - 创建了名为 "test.db" 的文件,并使用 SQLite3 连接到该文件。 - 创建了 "position_info" 表,包含 id、equity、profit_loss、created_at 和 updated_at 五个字段。 2. **自增ID实现**: - 使用 `AUTOINCREMENT` 属性使主键 ID 自增。 - 插入两条数据并观察 ID 的变化,验证自增功能正常工作。 3. **创建时间和更新时间自动更新**: - 修改表结构,在列的定义中添加 `DEFAULT (DATETIME('now', 'localtime'))`,使得创建时间和更新时间自动更新。 - 使用触发器 `trigger_position_info_updated_at` 在数据更新时自动更新 `updated_at` 字段。 总的来说,文章详细地演示了如何在 SQLite3 数据库中实现自动增长的主键 ID、创建时间和更新时间的记录功能。

正文

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

以前开发系统时,用MysqlPostgres比较多,sqlite3接触不多,
这次使用,希望sqlite3也能提供几个基本的功能,比如:

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

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

1. 准备

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

$  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三个字段即可。

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表是否创建。

sqlite> .tables
position_info

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

表按照默认的方式创建之后, 发现插入一条数据很麻烦,
需要指定position_info表中所有5个字段才能插入成功。

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能够自动增长。

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。

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'))

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...> );

然后插入两条测试数据:

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字段没有变化,一直是插入数据时的那个时间。

更新前:

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

更新第一条数据:

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字段。

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;

再更新一次数据看看:

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如下:

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;

与sqlite3自动插入创建时间和更新时间相似的内容:

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

最近在记录一些简单的结构化日志信息时,用到了sqlite3数据库(保存的信息比较简单,用Mysql,SQL Server,Postgres这些数据库有点小题大做)。 以前开发系统时,用Mysql和Postgres比较多,sqlite3接触不多,这次使用,希望sqlite3也能提供几个基本的功能,比如

python | 连接数据库

介绍一些python中用于连接常用数据库的依赖库。 SQLite3 SQLite3是Python 中自带的数据库模块,适用于小型应用和快速原型开发。 SQLite是一个进程内的库,实现了自给自足的、无服务器的、是非常小的,是轻量级的、事务性的 SQL 数据库引擎。它是一个零配置的数据库,不需要在系统

【逆向专题】【危!!!刑】(一)使用c#+Win32Api实现进程注入到wechat

引言 自从上篇使用Flaui实现微信自动化之后,这段时间便一直在瞎研究微信这方面,目前破解了Window微信的本地的Sqlite数据库,使用Openssl,以及Win32Api来获取解密密钥,今天作为第一张,先简单写一下,获取微信的一些静态数据,以及将自己写的c语言dll通过Api注入到微信进程里面

[转帖]jmeter实现不写代码把测试结果存入execl

这里使用数据库作为中间件来实现不写代码就把测试结果存入execl,下面是步骤 1.新建一个setup线程组用来设置数据库连接信息和新建数据库,如下图所示,我们使用sqlite数据库来存储信息,因为不需要自己再去安装数据库,Database URL填写jdbc:sqlite:mytest.db,这是标

聊聊Mybatis框架原理

好久没有写博客了。最近工作中封装了一个类似ORM框架的东西。大概的原理就是将Excel数据初始化到本地sqlite数据库后,通过json配置文件,对数据库的数据做增删改查等操作。 其实大概的思考了下,就是半ORM框架mybatis的逻辑,只是我们自己封装的简陋蛮多。想想有现成的轮子没用,反而是自己写

sqlite3.OperationalError: no such function: JSON_VALID

``` Initializing database.. Traceback (most recent call last): File "d:\program files\python38\lib\site-packages\django\db\backends\utils.py", line 82

[转帖]USQL

usql is a universal command-line interface for PostgreSQL, MySQL, Oracle Database, SQLite3, Microsoft SQL Server, and many other databases including N

K3S +Helm+NFS最小化测试安装部署只需十分钟

作者:郝建伟 k3s 简介 官方文档:k3s 什么是k3s k3s 是一个轻量级的 Kubernetes 发行版 它针对边缘计算、物联网等场景进行了高度优化。 k3s 有以下增强功能: 打包为单个二进制文件。 使用基于 sqlite3 的轻量级存储后端作为默认存储机制。同时支持使用 etcd3、My

SQLite vs MySQL vs PostgreSQL对比总结

开发业务系统时,是绕不开RDBMS(关系型数据库)的。虽然现在诞生了各种NoSQL的数据库,RDBMS在业务系统中的严谨和优势依然无法取代。 近几年大大小小的项目中,常用的三种RDBMS(SQLite,MySQL,Postgres)都有多次接触过,一些使用心得记录如下,供大家参考。 1. SQLit

[MAUI 项目实战] 笔记App(二):数据库设计

@目录Sqlite配置创建实体笔记实体类笔记分组实体笔记片段实体笔记片段负载实体笔记片段仓库实体笔记模板(场景)实体笔记片段模板实体笔记片段模板负载实体配置EF创建映射迁移和种子数据项目地址 Sqlite配置 应用程序里使用Sqlite作为数据库,使用EntityFramworkCore作为ORM,