32 SQLITE数据库

数据库

1.数据库:能够对大批量数据进行增删改查的软件

2.数据库的分类:

1.关系型数据库

1.将数据存放在文件中

Oracle, MySql, SQlite

2.非关系数据库

1.将数据存放在内存中,内存数据库

Redis, Nosql

安装sudo apt-get install sqlite3

使用

进入:sqlite3 test.db 创建test.db文件

这些命令在 sqlite> 交互式环境中使用,不需要以分号结尾。

.help 显示所有可用命令的帮助信息 .help

.exit 或 .quit 退出 SQLite 交互式环境 .exit

.tables 显示当前数据库中的所有表 .tables *

.schema 显示表的创建语句(结构) .schema 表名

.databases 显示当前打开的数据库文件路径 .databases *

.indices 显示表的所有索引 .indices 表名

.dump 导出整个数据库为 SQL 脚本 .dump > backup.sql

.read 执行外部 SQL 脚本文件 .read script.sql

.output 将输出重定向到文件 .output result.txt

.mode 设置查询结果的显示模式 .mode column 或 .mode csv *

.headers on/off 显示/隐藏查询结果的列名 .headers on *

.nullvalue 设置 NULL 值的显示字符 .nullvalue NULL

.show 显示当前的设置状态 .show

.schema 查看表的创建结构 .schema student *

以 . 开头的点命令 ✅ 立即执行 sqlite> → (执行完回到 sqlite>)

SQL 语句以 ; 结尾 ✅ 立即执行 sqlite> → (执行完回到 sqlite>)

SQL 语句没有 ; ❌ 不执行,继续等待 sqlite> → ...> (进入续行模式)

多行 SQL 语句 ❌ 不执行,继续等待 sqlite> → ...> (直到输入 ;)

括号不匹配 ❌ 不执行,继续等待 sqlite> → ...> (直到括号闭合)

SQL语句:

支持的数据类型

NULL 表示空值。

INTEGER 有符号整数,根据值的大小,以 1、2、3、4、6 或 8 字节存储。

REAL 浮点数,以 8 字节的 IEEE 浮点数存储。

TEXT 文本字符串,使用数据库的编码(如 UTF-8)存储。

BLOB 二进制大对象,数据会按照输入时的原样进行存储。

1.create table语句

CREATE TABLE IF NOT EXISTS 表名 (

列名1 数据类型 约束,

列名2 数据类型 约束,

...

表级约束

);

IF NOT EXISTS:如果表已存在则不创建

表名和列名不区分大小写,但建议用大写关键字

CREATE TABLE IF NOT EXISTS student (

id INTEGER PRIMARY KEY AUTOINCREMENT,

name TEXT NOT NULL,

age INTEGER DEFAULT 18,

score REAL,

class TEXT,

create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP

);

id:自增主键,唯一标识每条记录

name:不能为空

age:默认为18

score:浮点数,可以为空

class:文本,可以为空

create_time:自动记录创建时间

2.insert into

-- 完整写法(指定列名,推荐)

INSERT INTO 表名 (列1, 列2, 列3, ...) VALUES (值1, 值2, 值3, ...);

-- 简写(不指定列名,必须按顺序提供所有列的值)

INSERT INTO 表名 VALUES (值1, 值2, 值3, ...);

必须按照列要求给出一行完整数据,否则会报错

例子:

-- 推荐写法:明确指定列名

INSERT INTO student (name, age, score, class)

VALUES ('张三', 20, 95.5, '高三1班');

-- 一次插入多条数据(效率高)

INSERT INTO student (name, age, score, class) VALUES

('赵六', 21, 78.5, '高三1班'),

('孙七', 20, 88.0, '高三3班'),

('周八', 22, 93.5, '高三2班');

-- 插入默认值或NULL

INSERT INTO student (name, age, score, class)

VALUES ('小明', DEFAULT, NULL, DEFAULT);

3.select

生成一张新的表,可以对内容进行筛选,可以排序

select (列名1, 列名2, ...) from 表名;

查看表明的所有内容

select * from 表名;

显示列名,默认关 .header on

更改显示格式,.mode 模式名称 可选参数, 默认为 .mode list

.width 5 10 8 6 -- 分别设置每列宽度

.mode column 左对其

4.where子句

SELECT 列名 FROM 表名 WHERE 条件;

UPDATE 表名 SET 列 = 值 WHERE 条件;

DELETE FROM 表名 WHERE 条件;

模糊查询(LIKE)

% 匹配任意字符(0个或多个) '张%' = 以"张"开头

_ 匹配单个字符 '张_' = "张"后面跟1个字符

-- 查询姓"张"的学生(名字以"张"开头)

SELECT * FROM student WHERE name LIKE '张%';

-- 查询名字包含"三"的学生

SELECT * FROM student WHERE name LIKE '%三%';

-- 查询名字是"张三"或"张四"(两个字)

SELECT * FROM student WHERE name LIKE '张_';

-- 查询名字以"三"结尾的学生

SELECT * FROM student WHERE name LIKE '%三';

空值查询(NULL)

-- 查询 class 为 NULL 的学生(注意:不能用 = NULL)

SELECT * FROM student WHERE class IS NULL;

-- 查询 class 不为 NULL 的学生

SELECT * FROM student WHERE class IS NOT NULL;

-- 错误写法(不会报错,但查不到任何结果)

SELECT * FROM student WHERE class = NULL; -- ❌ 永远查不到

AND 且(所有条件都满足) WHERE age > 18 AND score >= 90

OR 或(任意条件满足) WHERE age < 18 OR age > 25

NOT 非(取反) WHERE NOT age = 20

-- 年龄大于18 且 分数大于90

SELECT * FROM student WHERE age > 18 AND score > 90;

-- 年龄小于18 或 年龄大于25

SELECT * FROM student WHERE age < 18 OR age > 25;

-- 不是高三1班的学生

SELECT * FROM student WHERE NOT class = '高三1班';

BETWEEN ... AND ...(包含边界)

-- 年龄在18到22之间(包含18和22)

SELECT * FROM student WHERE age BETWEEN 18 AND 22;

-- 等价于

SELECT * FROM student WHERE age >= 18 AND age <= 22;

IN(匹配多个值)

-- 查询指定班级的学生

SELECT * FROM student WHERE class IN ('高三1班', '高三2班', '高三3班');

-- 等价于

SELECT * FROM student WHERE class = '高三1班' OR class = '高三2班' OR class = '高三3班';

-- 查询分数为90, 95, 100的学生

SELECT * FROM student WHERE score IN (90, 95, 100);

NOT IN(排除多个值)

-- 查询不是高三1班和高三2班的学生

SELECT * FROM student WHERE class NOT IN ('高三1班', '高三2班');

ORDER BY 排序

-- 查询年龄大于18的学生,按分数从高到低排序

SELECT * FROM student

WHERE age > 18

ORDER BY score DESC;

-- 先按班级排序,再按分数排序

SELECT * FROM student

WHERE age > 18

ORDER BY class ASC, score DESC;

LIMIT 限制条数

-- 查询分数最高的3个学生

SELECT * FROM student

ORDER BY score DESC

LIMIT 3;

如果每一行有其固定的ID

-- 查询 id=2 的行

SELECT * FROM student WHERE id = 2; 或 score >= 90, name = '赵%'

-- 更新 id=2 的行

UPDATE student SET age = 23 WHERE id = 2;

-- 删除 id=2 的行

DELETE FROM student WHERE id = 2;

drop table

DROP TABLE IF EXISTS 表名;

IF EXISTS:如果表存在则删除,不存在也不报错

-- 删除 student 表(如果存在)

DROP TABLE IF EXISTS student;

-- 删除 student 表(如果不存在会报错)

DROP TABLE student;

多表联合查询

单引号 ' ' 包裹字符串和文本值 WHERE name = '张三'

双引号 " " 包裹标识符(表名、列名) SELECT "name" FROM "student"

当 id 设置为 INTEGER PRIMARY KEY AUTOINCREMENT 后,插入时系统会自动生成唯一 ID,你完全不用管它

joins

cross join;

SELECT * FROM 表1 CROSS JOIN 表2;

-- 创建颜色表

CREATE TABLE colors (color TEXT);

INSERT INTO colors VALUES ('红色'), ('蓝色'), ('绿色');

-- 创建尺寸表

CREATE TABLE sizes (size TEXT);

INSERT INTO sizes VALUES ('S'), ('M'), ('L');

-- CROSS JOIN 查询

SELECT * FROM colors CROSS JOIN sizes;

color size


红色 S

红色 M

红色 L

蓝色 S

蓝色 M

蓝色 L

绿色 S

绿色 M

绿色 L

-- 生成所有颜色×尺寸组合(电商SKU)

SELECT c.color, s.size, 'SKU_' || c.color || '_' || s.size AS sku_code

FROM colors c CROSS JOIN sizes s;

color size sku_code


红色 S SKU_红色_S

红色 M SKU_红色_M

红色 L SKU_红色_L

蓝色 S SKU_蓝色_S

...

查看时使用现有表信息的列来新建列名

select 表名.列名 as 新列名,...

innre join;

SELECT 列名列表

FROM 表1

INNER JOIN 表2 ON 表1.关联列 = 表2.关联列

INNER JOIN ...;

SELECT

student.name AS 学生,

course.course_name AS 课程,

score.score AS 分数,

course.teacher AS 老师

FROM student

INNER JOIN score ON student.id = score.student_id

INNER JOIN course ON score.subject = course.course_name;

outer join;

SELECT 列名列表

FROM 左表

LEFT JOIN 右表 ON 左表.关联列 = 右表.关联列;

左为主,将右表信息对齐左表

==============================================================================================

sqlite函数接口

sqlite3 *pdb; //pdb就是句柄

sqlite3_open;

int sqlite3_open(

const char *filename, /* 数据库文件名,UTF-8编码 */

sqlite3 **ppDb /* 输出参数:指向数据库连接句柄的指针 */

);

功能:

打开数据库文件,修改定义的sqlite3 *pdb的pdb为指向数据库的句柄指针

参数:

filename const char*

输入参数:数据库文件的路径(UTF-8编码)。

• 可以是绝对路径:"/home/user/data.db"

• 可以是相对路径:"mydb.db"

• 特殊值:":memory:"(内存数据库)

• 特殊值:""(临时磁盘数据库)

ppDb sqlite3**

输出参数:指向 sqlite3* 类型变量的指针。

• 函数执行成功后,会在这里填入一个有效的数据库连接句柄。

• 后续的 SQL 操作都通过这个句柄进行。

• 使用前必须先声明 sqlite3 *db;,然后传入 &db。

返回值:

成功返回0,

SQLITE_OK 0 0 成功:数据库打开成功,连接已建立。

SQLITE_ERROR 1 1 SQL错误或缺失数据库:通用错误。

SQLITE_INTERNAL 2 2 内部逻辑错误。

SQLITE_PERM 3 3 权限不足(无读写权限)。

SQLITE_ABORT 4 4 操作被中止。

SQLITE_BUSY 5 5 数据库被其他进程锁定。

SQLITE_LOCKED 6 6 数据库表被锁定。

SQLITE_NOMEM 7 7 内存分配失败。

SQLITE_READONLY 8 8 数据库文件只读,无法写入。

SQLITE_INTERRUPT 9 9 操作被中断。

SQLITE_IOERR 10 10 磁盘I/O错误:无法读取或写入文件。

SQLITE_CORRUPT 11 11 数据库文件损坏。

SQLITE_NOTFOUND 12 12 数据库文件不存在(但 sqlite3_open 会自动创建)。

SQLITE_FULL 13 13 磁盘空间已满。

SQLITE_CANTOPEN 14 14 无法打开文件:路径无效或权限不足。

SQLITE_PROTOCOL 15 15 锁定协议错误。

SQLITE_EMPTY 16 16 空文件。

SQLITE_SCHEMA 17 17 数据库schema已改变。

SQLITE_TOOBIG 18 18 数据太大(超过限制)。

SQLITE_CONSTRAINT 19 19 违反约束条件。

SQLITE_MISMATCH 20 20 数据类型不匹配。

SQLITE_MISUSE 21 21 API使用错误(如用 sqlite3_open 已打开的连接)。

SQLITE_NOLFS 22 22 不支持大文件系统。

SQLITE_AUTH 23 23 授权失败。

SQLITE_FORMAT 24 24 文件格式错误。

SQLITE_RANGE 25 25 参数超出范围。

SQLITE_NOTADB 26 26 不是数据库文件:文件头错误。

打印错误,fprintf(stderr, "%s\n", sqlite3_errmsg(pdb));

const char *sqlite3_errmsg(sqlite3 *db);

参数 db:数据库连接句柄(由 sqlite3_open 获得)

返回值 const char*:指向错误信息字符串的指针(UTF-8 编码)

目库存在,文件不存在会自动创建空白的.db文件

=============================================================================================

sqlite3_exec;

int sqlite3_exec(

sqlite3 *db, /* 数据库连接句柄 */

const char *sql, /* 要执行的 SQL 语句(可多条) */

int (*callback)(void *data, int argc, char **argv, char **col_name), // 回调函数(查询结果处理

void *data, /* 回调函数的第一个参数(用户数据) */

char **errmsg /* 错误信息输出(需要手动释放) */

);

功能: 执行一条SQL语句

参数:

db sqlite3* 数据库连接句柄 由sqlite3_open获得

sql const char* 要执行的 SQL 语句(可以包含多条语句,用 ; 分隔)

callback int (*)(void*, int, char**, char** ) 回调函数:处理 SELECT 查询结果的每一行,如果是 INSERT/UPDATE/DELETE 等非查询语句,传 NULL, 如果正常执行一定要return 0;

data void* 用户自定义数据,会原样传给回调函数的第一个参数

errmsg char** 输出参数:如果出错,返回错误信息字符串,使用完后必须调用 sqlite3_free(errmsg) 释放

返回值:

SQLITE_OK (0) 执行成功

其他错误码 执行失败(如 SQLITE_ERROR、SQLITE_CONSTRAINT 等)

void *arg 第一个参数,自定义传入参数

colnum 列数

pcontent 列的内容指针数组

ptitle 列的名称指针数组

该回调函数,会随着select每找到一个数据就会被调用一次

如果select没有找到,不会执行

int callbackfun(void *arg, int colnum, char **pcontent, char **ptitle)

{

return 0; //如果不返回0,会报错

}

void sqlite3_free(void *p);

参数 p:指向要释放的内存块的指针(由 SQLite API 返回)

返回值 无(void)

特性 如果传入 NULL,函数不做任何事(安全)

sqlite3_exec的最后一个参数是一个字符串的二级指针,如果出错,sqlite3_exec会将其对指向的一级指针的值更改为指向错误信息的指针,打印错误之后可以将其释放

例子

char *perrmsg = NULL;

int sqexecret = sqlite3_exec(pdb, cmd, NULL, NULL, &perrmsg);

if (sqexecret != SQLITE_OK)

{

fprintf(stderr, "sqlite_exec error %s\n", perrmsg);

sqlite3_free(perrmsg);

return -1;

}

================================================================================================

sqlite3_close

int sqlite3_close(sqlite3 *db);

功能 关闭一个 SQLite 数据库连接

参数 db:要关闭的数据库连接句柄(由 sqlite3_open 获得)

返回值 SQLITE_OK (0):成功关闭

SQLITE_BUSY (5):连接仍有未提交事务或未释放的语句

相关推荐
JavaPub-rodert1 小时前
Redis 和 MySQL 如何保证数据一致性?从业务方案到底层原理完整讲解
数据库·redis·mysql
大牧师1 小时前
TypeORM 学习教程
数据库·sql·学习·node.js·orm·nest.js·typeorm
IvorySQL1 小时前
PostgreSQL 日报| PGQ 功能发现严重缺陷(9 月 4 日)
数据库·postgresql
后台模板学习1 小时前
用 IM 即时聊天项目一次讲清消息去重算法的踩坑与解决方案
java·数据库·spring
imbackneverdie1 小时前
国内有哪些比较全面的生物医学相关数据库?
大数据·数据库·人工智能·ai·信息可视化·aigc·科研
数字智核2 小时前
2026昆山工厂空压机突然停机怎么办?找谁抢修
服务器·网络·数据库
AAA代码批发商2 小时前
Days 39 Linux C 开发之 SQLite 数据库完整学习笔记
linux·c语言·数据库
笑梦无境2 小时前
mysql的安装及配置(3)
数据库·mysql·adb
电商API_180079052472 小时前
跨境1688代采商家,如何借助API打通供应链,实现效率跃迁
大数据·数据库·网络爬虫