一、SQLite3 数据库创建与基础操作
1. 数据库创建
通过命令行工具快速创建并进入 SQLite3 数据库:
- 创建数据库文件:
touch xxx.db
(xxx 为自定义数据库名称,如test.db
) - 进入数据库交互环境:
sqlite3 xxx.db
(执行后进入 SQLite 命令行,提示符为sqlite>
)
2. 系统维护命令(.
开头)
所有系统维护命令均以 .
起始,可通过 .help
查看完整列表,核心命令如下:
命令 | 功能描述 | 示例 |
---|---|---|
.help |
查看所有系统维护命令的帮助信息 | sqlite> .help |
.database |
列出当前关联的数据库及对应的文件路径 | sqlite> .database |
.tables |
列出当前数据库中所有的表 | sqlite> .tables |
.schema 表名 |
查看指定表的结构(字段、类型、约束等) | sqlite> .schema user (查看 user 表结构) |
.dump 表名 |
导出指定表的数据与结构;不加表名则导出整个数据库 | sqlite> .dump user (导出 user 表) |
3. 数据库导入与导出(重定向)
导出数据库
将数据库内容导出为 SQL 脚本文件,便于备份或迁移:
sqlite3 test.db .dump > backup.sql # 将 test.db 导出到 backup.sql
导入数据库
从 SQL 脚本文件恢复数据库内容:
sqlite3 new.db < backup.sql # 将 backup.sql 导入到 new.db
二、标准 SQL 语句(通用语法)
所有 SQL 语句必须以 ;
结尾,核心操作包括表的创建 / 删除、数据的增删改查(CRUD)。
1. 数据类型
SQLite3 支持的核心数据类型如下,未指定类型时默认为 TEXT
:
INT
:整数类型(如年龄、ID)TEXT
:文本类型(如姓名、描述)REAL
:浮点数类型(如价格、分数)BLOB
:二进制类型(如图片、文件)
2. 表结构操作(DDL)
创建表(CREATE TABLE)
语法:CREATE TABLE 表名 (字段1 类型, 字段2 类型, ...);
示例:
-- 简单创建(默认 TEXT 类型)
CREATE TABLE user (id, name, age);
-- 指定类型创建(推荐)
CREATE TABLE user (id INT, name TEXT, age INT);
删除表(DROP TABLE)
语法:DROP TABLE 表名;
(删除表结构及所有数据,谨慎使用)
示例:
DROP TABLE user; # 删除 user 表
3. 数据操作(DML)
1. 插入数据(INSERT INTO)
向表中添加一条或多条数据,支持指定字段或全字段插入。
语法 1(指定字段):INSERT INTO 表名 (字段1, 字段2, ...) VALUES (值1, 值2, ...);
语法 2(全字段):INSERT INTO 表名 VALUES (值1, 值2, ...);
(值的顺序需与表字段顺序一致)
-- 向 user 表插入数据(指定 id 和 age)
INSERT INTO user (id, age) VALUES (1, 10);
-- 全字段插入(id=3, name="wang", age=11)
INSERT INTO user VALUES (3, "wang", 11);
-- 仅插入 age(其他字段为 NULL)
INSERT INTO user (age) VALUES (12);
2. 查询数据(SELECT)
从表中筛选数据,支持指定列、条件过滤、排序、限制结果数量。
语法:SELECT 列名 FROM 表名 [WHERE 条件] [ORDER BY 列名 排序方式] [LIMIT 数量];
核心参数说明:
*
:表示查询所有列WHERE
:筛选条件(支持>
,<
,=
,AND
,OR
,NOT
,以及通配符%
匹配任意字符、_
匹配单个字符)ORDER BY 列名 ASC/DESC
:按指定列排序(ASC
升序,默认;DESC
降序)LIMIT 数量
:限制返回结果的行数
示例:
-- 查询 user 表所有数据
SELECT * FROM user;
-- 仅查询 id 列
SELECT id FROM user;
-- 查询 age 不小于 30 的数据(NOT age < 30 等价于 age >= 30)
SELECT id, name FROM user WHERE NOT age < 30;
-- 查询 name 包含“三”的用户(% 匹配任意字符)
SELECT * FROM user WHERE name LIKE '%三%';
-- 查询 age 大于 20 或小于 50 的数据,按 age 降序,仅返回前 2 条
SELECT * FROM user WHERE age > 20 OR age < 50 ORDER BY age DESC LIMIT 2;
-- 查询日期在 2018-12-31 到 2022-01-01 之间的数据
SELECT * FROM user WHERE date > '2018-12-31' AND date < '2022-01-01';
3. 修改数据(UPDATE)
更新表中符合条件的数据,必须加 WHERE 条件,否则会修改所有数据。
语法:UPDATE 表名 SET 字段1=值1, 字段2=值2, ... [WHERE 条件];
-- 将 name 为“li”的用户 id 改为 1
UPDATE user SET id = 1 WHERE name = 'li';
-- 将 name 为“li”且 passwd 为“123”的用户 id 改为 1
UPDATE user SET id = 1 WHERE name = "li" AND passwd = "123";
-- 将 name 为“li”或“zhao”的用户 id 改为 2
UPDATE user SET id = 2 WHERE name = "li" OR name = "zhao";
4. 删除数据(DELETE)
删除表中符合条件的数据,不加 WHERE 条件会删除所有数据(表结构保留)。
语法:DELETE FROM 表名 [WHERE 条件];
-- 删除 user 表所有数据(谨慎使用)
DELETE FROM user;
-- 删除 id 为 1 的数据
DELETE FROM user WHERE id = 1;
-- 删除 id=1 且 name 为“zhang”的数据
DELETE FROM user WHERE id = 1 AND name = "zhang";
-- 删除 id=1 或 id=2 的数据
DELETE FROM user WHERE id = 1 OR id = 2;
三、SQLite3 C 语言编程接口
SQLite3 提供 C 语言接口,支持在程序中操作数据库,核心流程为:打开数据库 → 执行操作(增删改查) → 关闭数据库。
1. 环境准备
头文件
需包含 SQLite3 官方头文件:#include <sqlite3.h>
编译链接
编译时需链接 SQLite3 库,添加 -lsqlite3
参数,示例:
gcc test.c -o test -lsqlite3 # 编译 test.c 生成可执行文件 test
2. 核心接口函数
1. 打开数据库(sqlite3_open)
功能:打开指定路径的数据库文件,获取数据库句柄。
int sqlite3_open(const char *path, sqlite3 **db);
- 参数:
path
:数据库文件路径(如"./test.db"
)db
:输出参数,指向数据库句柄的指针(成功后通过该句柄操作数据库)
- 返回值:
- 成功:
0
(SQLITE_OK) - 失败:非 0(如文件路径错误、权限不足)
- 成功:
2. 关闭数据库(sqlite3_close)
功能:关闭已打开的数据库句柄,释放资源。
int sqlite3_close(sqlite3 *db);
- 参数:
db
:已打开的数据库句柄
- 返回值:
- 成功:
0
(SQLITE_OK) - 失败:非 0(如句柄无效、仍有未完成操作)
- 成功:
3. 执行非查询语句(sqlite3_exec)
功能:执行 INSERT、DELETE、UPDATE 等非查询 SQL 语句,支持回调函数(可选)。
int sqlite3_exec(sqlite3 *db, const char *sql, sqlite3_callback callback, void *arg, char **errmsg);
- 参数:
db
:数据库句柄sql
:要执行的 SQL 语句(如"INSERT INTO user VALUES (4, 'li', 20);"
)callback
:回调函数(仅执行查询语句时需使用,非查询时设为NULL
)arg
:传递给回调函数的参数(无回调时设为NULL
)errmsg
:输出参数,存储错误信息(需手动释放内存,避免内存泄漏)
- 返回值:
- 成功:
0
(SQLITE_OK) - 失败:非 0(错误信息存储在
errmsg
中)
- 成功:
示例(插入数据):
sqlite3 *db;
char *errmsg = NULL;
// 打开数据库
if (sqlite3_open("./test.db", &db) != SQLITE_OK) {
printf("打开数据库失败:%s\n", sqlite3_errmsg(db));
return -1;
}
// 执行插入语句
char *sql = "INSERT INTO user VALUES (5, 'zhao', 25);";
if (sqlite3_exec(db, sql, NULL, NULL, &errmsg) != SQLITE_OK) {
printf("插入失败:%s\n", errmsg);
sqlite3_free(errmsg); // 释放错误信息内存
sqlite3_close(db);
return -1;
}
// 关闭数据库
sqlite3_close(db);
4. 执行查询语句(sqlite3_get_table)
功能:执行 SELECT 语句,获取查询结果集(行数、列数、数据)。
int sqlite3_get_table(sqlite3 *db, const char *sql, char ***result, int *nrow, int *ncol, char **errmsg);
- 参数:
db
:数据库句柄sql
:要执行的查询 SQL 语句(如"SELECT * FROM user;"
)result
:输出参数,三级指针,存储查询结果(格式:result[0]
为列名,result[1]
开始为数据,按 “行优先” 存储)nrow
:输出参数,查询结果的行数(不含列名行)ncol
:输出参数,查询结果的列数errmsg
:输出参数,存储错误信息(需手动释放)
- 返回值:
- 成功:
0
(SQLITE_OK) - 失败:非 0(错误信息存储在
errmsg
中)
- 成功:
关键说明:
- 查询结果
result
需通过sqlite3_free_table(result)
释放,避免内存泄漏。 - 结果集格式示例(假设查询
id, name
,返回 2 行数据):plaintext
result[0] = "id", result[1] = "name" // 列名 result[2] = "1", result[3] = "wang" // 第一行数据 result[4] = "2", result[5] = "li" // 第二行数据
示例(查询数据):
sqlite3 *db;
char **result;
int nrow, ncol;
char *errmsg = NULL;
// 打开数据库
if (sqlite3_open("./test.db", &db) != SQLITE_OK) {
printf("打开失败:%s\n", sqlite3_errmsg(db));
return -1;
}
// 执行查询语句
char *sql = "SELECT id, name FROM user;";
if (sqlite3_get_table(db, sql, &result, &nrow, &ncol, &errmsg) != SQLITE_OK) {
printf("查询失败:%s\n", errmsg);
sqlite3_free(errmsg);
sqlite3_close(db);
return -1;
}
// 打印结果(先打印列名,再打印数据)
printf("列名:");
for (int i = 0; i < ncol; i++) {
printf("%s\t", result[i]);
}
printf("\n数据:\n");
for (int i = 0; i < nrow; i++) {
for (int j = 0; j < ncol; j++) {
// 数据从 result[ncol] 开始,每行有 ncol 个元素
printf("%s\t", result[ncol + i * ncol + j]);
}
printf("\n");
}
// 释放结果集和数据库资源
sqlite3_free_table(result);
sqlite3_close(db);
3. 编程框架总结
#include <sqlite3.h>
#include <stdio.h>
int main() {
sqlite3 *db = NULL;
char *errmsg = NULL;
// 1. 打开数据库
if (sqlite3_open("./test.db", &db) != SQLITE_OK) {
printf("打开数据库失败:%s\n", sqlite3_errmsg(db));
return -1;
}
// 2. 执行操作(增删改查)
// (示例:插入数据)
char *sql = "INSERT INTO user (id, name, age) VALUES (6, 'sun', 30);";
if (sqlite3_exec(db, sql, NULL, NULL, &errmsg) != SQLITE_OK) {
printf("操作失败:%s\n", errmsg);
sqlite3_free(errmsg);
sqlite3_close(db);
return -1;
}
// 3. 关闭数据库
sqlite3_close(db);
printf("操作成功!\n");
return 0;
}