sqlite3自动插入创建时间和更新时间
最近在记录一些简单的结构化日志信息时,用到了sqlite3数据库(保存的信息比较简单,用Mysql,SQL Server,Postgres这些数据库有点小题大做)。
以前开发系统时,用Mysql和Postgres比较多,sqlite3接触不多,
这次使用,希望sqlite3也能提供几个基本的功能,比如:
- 主键ID自增
- 插入数据时,自动更新创建时间(created_at)
- 更新数据时,自动更新更新时间(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,这是我用来记录账户净值和利润的表,其中字段的作用不用管,
只需要关注 id,created_at,updated_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
其实,我希望实现的是插入和更新时,只关注equity和profit_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
现在,我们只要关注equity和profit_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
第一条数据的equity和profit_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自动插入创建时间和更新时间的更多相关文章
- spring data jpa之Auditing 表的创建时间,更新时间自动生成策略
		java实际编程中,几乎每一张表都会有createTime和updateTime字段,spring的优秀之处在于只要用几个注解,就帮我们解决该类问题,具体实现: 1,实体类添加注解: @EntityL ... 
- JPA注解实体类,给表添加创建时间,更新时间,id的生成以及创建唯一约束
		首先创建一个BaseModel,自动生成创建时间和更新时间 @SuppressWarnings("serial") @MappedSuperclass public class B ... 
- Laravel / Lumen 框架修改 创建时间 和 更新时间 对应字段
		为避免浪费时间--先上解决方案 在Model中重写 CREATED_AT 和 UPDATED_AT 两个类常量就可以了,这两个常量分别是创建时间和更新时间的字段名. ================= ... 
- C#获得指定目录床架时间、更新时间和最后访问时间等信息的代码
		将做工程过程常用的内容片段备份一次,下面的内容内容是关于C#获得指定目录床架时间.更新时间和最后访问时间等信息的内容,希望能对小伙伴们也有用. using System;using System.IO ... 
- Spring Date Jpa on update current_timestamp 自动维护创建时间和更新时间
		在数据库里设置默认值current_timestamp可以维护创建时间,设置on update current_timestamp 可以维护更新时间.在JPA中应该如何去做呢?这里还是以上篇Topic ... 
- django学习-24.创建时间和更新时间的添加
		目录结构 1.前言 2.入参auto_now和入参auto_now_add 2.1.入参auto_now的相关知识点 2.2.入参auto_now_add的相关知识点 3.完整的操作流程 3.1.第一 ... 
- mysql中创建时间和更新时间的区别
		`create_time` ) NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `update_time` ) ) COMMENT '更新时间', 而在界 ... 
- mysql 表字段 记录创建时间和更新时间
		sql语句创建: CREATE TABLE `NewTable` ( `id` int NOT NULL AUTO_INCREMENT , `name` varchar(20) NOT NULL , ... 
- 创建时间和更新时间两个选一个的情况和select case when ... then ... else ... end from 表 的使用
		1.查询时间,如果更新时间update_time为空就查创建时间create_time,否则查更新时间update_time select update_time,create_time, case ... 
- Ubuntu 16 , 从时间服务器更新时间
		因为在公司的内网,所以不能用Ubuntu默认的服务器去更新时间. 只能改成从网关 10.182.202.2 上取时间 1) 如果没有安装ntp 的话,先安装 apt-get install ntp 2 ... 
随机推荐
- MD5前端vue加密
			Vue 前端md5加密用户注册时将加密后的密码发送给后端存储当登陆的时候,再将加密后的密码和数据库中加密的密码相匹配.npm: https://www.npmjs.com/package/crypto ... 
- 【笔记】Oracle列转行unpivot&行转列 PIVOT
			unpivot 说明:将表中多个列缩减为一个聚合列(多列转多行) 语法:unpivot(新列名 for 聚合列名 in (对应的列名1-列名n )) 写到了一个力扣的题,发现这个unpivot函数还没 ... 
- 从零开始入门 K8s | 调度器的调度流程和算法介绍
			导读:Kubernetes 作为当下最流行的容器自动化运维平台,以声明式实现了灵活的容器编排,本文以 v1.16 版本为基础详细介绍了 K8s 的基本调度框架.流程,以及主要的过滤器.Score 算法 ... 
- 基于 OPLG 从 0 到 1 构建统一可观测平台实践
			简介: 随着软件复杂度的不断提升,单体应用架构逐步向分布式和微服务的架构演进,整体的调用环境也越来越复杂,仅靠日志和指标渐渐难以快速定位复杂环境下的问题.对于全栈可观测的诉求也变得愈加强烈,Trace ... 
- 评审恩仇录——IDE也能做代码评审?
			简介: 云效Codeup推出了本地IDE插件端的评审,免除了黄药师来回华山的奔波之苦 现代科技公司的同事们平日一起交流开发规约和产品需求,肩上共同扛着业务发展和同行竞争的压力,这份还书贻剑的情谊如何能 ... 
- [Gin] 单文件极简 HTTP Server 流程分析 ( gin-gonic/gin )
			/** * example.go * * @link https://cnblogs.com/farwish */package main import "github.com/gin-go ... 
- [Python急救站]基于Transformer Models模型完成GPT2的学生AIGC学习训练模型
			为了AIGC的学习,我做了一个基于Transformer Models模型完成GPT2的学生AIGC学习训练模型,指在训练模型中学习编程AI. 在编程之前需要准备一些文件: 首先,先win+R打开运行 ... 
- 都2024年了,你还不知道git worktree么?
			三年前 python 大佬吉多·范罗苏姆(为 Python 程序设计语言的最初设计者及主要架构师)才知道 git worktree ,我现在才知道,我觉得没啥丢人的. 应用场景 如果你正在 featu ... 
- 一次glide内存泄漏排查分析
			glide是一款非常优秀的图片加载框架,目前很多项目在使用.提供了非常方法,在此,笔者就不一一列举了,可以到官网查找. 目前项目在做内存排查,因为是车机项目,之前开发的时候没有注意内存方面的问题(车机 ... 
- Java简单实现MQ架构和思路01
			实现一个 MQ(消息队列)架构可以涉及到很多方面,包括消息的生产和消费.消息的存储和传输.消息的格式和协议等等.下面是一个简单的 MQ 架构的实现示例,仅供参考: 定义消息格式和协议:我们可以定义一个 ... 
