Linux环境下SQLite简单实现(附示例说明)
作者:!99%
SQLite 数据库常用操作指令总结
SQLite 是轻量级嵌入式数据库,无需服务端,操作指令简洁直观。以下按数据库管理、表操作、数据增删改查(CRUD)、进阶操作四大类,整理最常用的核心指令,并附示例说明。
一、数据库基础管理
SQLite 数据库以单个文件存储(如 test.db),以下指令用于数据库的创建、连接与状态查看。
操作目的 | 指令格式 | 示例与说明 |
连接/创建数据库 |
|
|
查看当前连接的数据库 |
| 执行后显示当前连接的数据库文件路径(如 |
退出 SQLite 命令行 |
| 输入 |
二、数据表核心操作
数据表是存储数据的载体,需先定义表结构(字段名、数据类型、约束),再进行后续操作。
1. 创建表(CREATE TABLE)
格式:
CREATE TABLE [IF NOT EXISTS] 表名 (
字段1 数据类型 [约束],
字段2 数据类型 [约束],
...
[主键约束/外键约束]
);关键说明:
IF NOT EXISTS:可选,避免表已存在时报错。- SQLite 常用数据类型:
INTEGER(整数)、TEXT(字符串)、REAL(浮点数)、BLOB(二进制,如图片)、NUMERIC(自动适配数值类型)。 - 常见约束:
PRIMARY KEY(主键,唯一且非空)、NOT NULL(字段不可为空)、UNIQUE(字段值唯一)、DEFAULT [值](默认值)。
示例:创建 user 表(存储用户信息)
CREATE TABLE IF NOT EXISTS user (
id INTEGER PRIMARY KEY AUTOINCREMENT, -- 主键,自动递增(AUTOINCREMENT 仅 INTEGER 可用)
name TEXT NOT NULL, -- 用户名,非空
age INTEGER DEFAULT 18, -- 年龄,默认18
email TEXT UNIQUE, -- 邮箱,唯一(避免重复注册)
create_time TEXT DEFAULT (datetime('now', 'localtime')) -- 注册时间,默认当前本地时间
);2. 查看表相关信息
操作目的 | 指令格式 | 示例与说明 |
查看所有表名 |
| 执行后显示当前数据库中所有表(如 |
查看表结构(字段详情) |
|
|
3. 修改表结构(ALTER TABLE)
SQLite 对 ALTER TABLE 支持有限,仅支持重命名表和添加字段,不支持删除/修改已有字段(需间接实现,如建新表迁移数据)。
操作目的 | 指令格式 | 示例与说明 |
重命名表 |
|
|
给表添加新字段 |
|
|
4. 删除表(DROP TABLE)
格式:
DROP TABLE [IF EXISTS] 表名;
示例:
DROP TABLE IF EXISTS users; -- 若 `users` 表存在则删除,避免报错
三、数据增删改查(CRUD)
数据表创建后,核心操作是对数据的新增、删除、修改和查询。
1. 新增数据(INSERT)
向表中插入一条或多条记录。
格式1:指定字段插入(推荐,字段顺序可自定义)
INSERT INTO 表名 (字段1, 字段2, ...) VALUES (值1, 值2, ...);
格式2:不指定字段(需按表结构字段顺序插入所有值)
INSERT INTO 表名 VALUES (值1, 值2, ...); -- 主键若为 AUTOINCREMENT,可传 NULL 自动生成
格式3:批量插入
INSERT INTO 表名 (字段1, 字段2, ...) VALUES (值1-1, 值1-2, ...), (值2-1, 值2-2, ...), ...;
示例:向 user 表插入数据
-- 1. 指定字段插入(忽略 id,自动递增;忽略 create_time,用默认时间)
INSERT INTO user (name, age, email) VALUES ('张三', 25, 'zhangsan@test.com');
-- 2. 批量插入
INSERT INTO user (name, age, email) VALUES
('李四', 30, 'lisi@test.com'),
('王五', 22, 'wangwu@test.com');注意:字符串值需用 '单引号' 包裹,数值类型直接写(如 25 无需引号)。
2. 查询数据(SELECT)
SQLite 最核心的操作,用于从表中筛选、排序、限制数据,语法灵活。
基础格式(查询所有字段/指定字段)
-- 查询指定字段 SELECT 字段1, 字段2, ... FROM 表名; -- 查询所有字段(* 表示所有) SELECT * FROM 表名;
带条件查询(WHERE)
筛选符合条件的记录,支持 =、!=、>、<、>=、<=、LIKE(模糊匹配)、IN(范围匹配)等条件。
SELECT * FROM user WHERE age > 23; -- 查询年龄大于23的用户 SELECT name, email FROM user WHERE email LIKE '%test.com'; -- 模糊匹配邮箱以 test.com 结尾的用户 SELECT * FROM user WHERE age IN (22, 25, 30); -- 查询年龄为22、25、30的用户
排序(ORDER BY)
按指定字段升序(ASC,默认)或降序(DESC)排列结果。
SELECT * FROM user ORDER BY age DESC; -- 按年龄降序排列(从大到小) SELECT name, age FROM user ORDER BY age ASC, name DESC; -- 先按年龄升序,再按姓名降序
限制结果数量(LIMIT)
只返回前 N 条记录,常用于分页(搭配 OFFSET 实现分页,OFFSET M 表示跳过前 M 条)。
SELECT * FROM user LIMIT 2; -- 返回前2条记录 SELECT * FROM user ORDER BY age DESC LIMIT 2 OFFSET 1; -- 跳过第1条,返回接下来的2条(即第2、3条)
去重(DISTINCT)
去除结果中重复的记录(基于指定字段)。
SELECT DISTINCT age FROM user; -- 查询所有不重复的年龄
统计(COUNT/SUM/AVG 等聚合函数)
COUNT(*):统计记录总数;COUNT(字段):统计该字段非空值的数量。SUM(字段):计算字段值总和;AVG(字段):计算字段值平均值。
<code>SELECT COUNT(*) AS user_count FROM user; -- 统计用户总数,结果列名用 AS 改为 user_count SELECT AVG(age) AS avg_age FROM user; -- 计算用户平均年龄 SELECT SUM(age) FROM user WHERE age > 25; -- 计算年龄大于25的用户年龄总和</code>
3. 修改数据(UPDATE)
更新表中符合条件的记录,必须加 WHERE 条件,否则会修改所有记录!
格式:
UPDATE 表名 SET 字段1=新值1, 字段2=新值2, ... [WHERE 条件];
示例:
-- 将张三的年龄改为26(指定 WHERE 条件,仅修改张三) UPDATE user SET age=26 WHERE name='张三'; -- 将所有年龄小于20的用户,默认年龄改为19(批量修改,需谨慎) UPDATE user SET age=19 WHERE age < 20;
4. 删除数据(DELETE)
删除表中符合条件的记录,必须加 WHERE 条件,否则会删除所有记录!
格式:
DELETE FROM 表名 [WHERE 条件];
示例:
-- 删除邮箱为 wangwu@test.com 的用户 DELETE FROM user WHERE email='wangwu@test.com'; -- 删除年龄大于35的用户 DELETE FROM user WHERE age > 35;
四、进阶操作
1. 事务管理(BEGIN/COMMIT/ROLLBACK)
SQLite 支持事务,确保一组操作要么全部成功,要么全部失败(避免数据不一致)。
BEGIN TRANSACTION;或BEGIN;:开始事务。COMMIT;:提交事务(所有操作生效,持久化到数据库)。ROLLBACK;:回滚事务(取消事务内所有未提交的操作)。
示例:批量插入数据,出错则回滚
BEGIN;
INSERT INTO user (name, email) VALUES ('赵六', 'zhaoliu@test.com');
INSERT INTO user (name, email) VALUES ('孙七', 'sunqi@test.com'); -- 若此句报错(如邮箱重复)
COMMIT; -- 报错则执行 ROLLBACK,两句插入都不生效2. 索引(CREATE INDEX)
索引用于加速查询(尤其表数据量大时),但会增加插入/修改/删除的耗时(需维护索引)。
格式:
CREATE [UNIQUE] INDEX [IF NOT EXISTS] 索引名 ON 表名 (字段1, 字段2, ...);
示例:
-- 给 user 表的 email 字段创建唯一索引(避免重复,同时加速邮箱查询) CREATE UNIQUE INDEX IF NOT EXISTS idx_user_email ON user (email); -- 给 age 字段创建普通索引(加速年龄相关查询) CREATE INDEX IF NOT EXISTS idx_user_age ON user (age);
删除索引:
DROP INDEX IF EXISTS 索引名; -- 如 DROP INDEX idx_user_age;
五、常用辅助指令(命令行特有)
SQLite 命令行中,以 . 开头的指令用于辅助操作,非 SQL 标准语法:
.help:查看所有 SQLite 命令行指令帮助。.mode column:以表格形式显示查询结果(更易读)。.header on:显示查询结果的字段名(配合.mode column使用)。.read [SQL文件路径]:执行外部 SQL 文件(如.read init.sql,执行init.sql中的所有指令)。
六、关键注意事项
- SQL 指令大小写不敏感:
SELECT和select效果一致,但建议关键字(如SELECT、INSERT)大写,表名/字段名小写,提高可读性。 - 字符串用单引号:SQLite 中字符串必须用
'单引号'包裹,双引号可能报错(不同数据库兼容问题)。 - 主键自动递增:仅
INTEGER类型的主键可加AUTOINCREMENT,插入时传NULL即可自动生成唯一ID。 - 避免误操作:
UPDATE和DELETE必须加WHERE条件,否则会修改/删除全表数据(无回收站,无法恢复)。
SQLite3 C语言实现增删改查知识点小结
SQLite3 是轻量级嵌入式数据库,无需独立服务,通过 C 语言 API 可直接操作。以下总结核心知识点、常用 API 及简化版增删改查案例,避免复杂判断,聚焦基础功能实现。
一、核心知识点与常用 API
1. 编译与链接
- 依赖:需包含 SQLite3 头文件
sqlite3.h,链接时添加 SQLite3 库(如 Linux 下-lsqlite3,Windows 下链接sqlite3.lib)。 - 编译命令示例(Linux):
gcc main.c -o sqlite_demo -lsqlite3
2. 核心 API 说明
API 函数原型 | 功能说明 | 关键参数/返回值 |
| 打开/创建数据库 | - |
| 执行 SQL 语句(增、删、改、查均可用,查需配合回调) | - |
| 关闭数据库 | - 需确保所有 SQL 操作完成后调用 |
| 释放错误信息内存 | - 必须释放 |
回调函数原型: | 查询时每行数据的处理函数(自动被 | - |
二、简化版增删改查案例
以下案例实现一个 student 表(包含 id 主键、name 姓名、age 年龄)的完整操作,代码无复杂判断,仅保留核心逻辑。
步骤 1:完整代码实现
#include <stdio.h>
#include <sqlite3.h>
#include <stdlib.h>
// 1. 查询回调函数:打印每行查询结果
int query_callback(void *arg, int col_num, char **col_val, char **col_name) {
// 打印列名(仅第一行数据时打印一次)
static int is_first_row = 1;
if (is_first_row) {
for (int i = 0; i < col_num; i++) {
printf("%-10s", col_name[i]); // 左对齐,占10字符
}
printf("\n");
is_first_row = 0;
}
// 打印当前行数据
for (int i = 0; i < col_num; i++) {
// 若值为NULL,显示"NULL",否则显示值
printf("%-10s", col_val[i] ? col_val[i] : "NULL");
}
printf("\n");
return 0; // 继续遍历下一行
}
int main() {
sqlite3 *db = NULL; // 数据库句柄
char *err_msg = NULL; // 错误信息
int ret; // API返回值
// 2. 打开/创建数据库(若不存在则自动创建)
ret = sqlite3_open("student.db", &db);
if (ret != SQLITE_OK) {
printf("打开数据库失败:%s\n", sqlite3_errmsg(db));
sqlite3_close(db);
return 1;
}
printf("打开数据库成功!\n");
// 3. 创建表(若表不存在则创建)
const char *create_sql = "CREATE TABLE IF NOT EXISTS student ("
"id INT PRIMARY KEY," // 主键(唯一标识)
"name TEXT," // 姓名
"age INT);"; // 年龄
ret = sqlite3_exec(db, create_sql, NULL, NULL, &err_msg);
if (ret != SQLITE_OK) {
printf("创建表失败:%s\n", err_msg);
sqlite3_free(err_msg); // 释放错误信息
sqlite3_close(db);
return 1;
}
printf("创建表成功(或表已存在)!\n");
// 4. 插入数据(增)
const char *insert_sql = "INSERT INTO student (id, name, age) "
"VALUES (1, 'Zhang San', 20), " // 插入2条数据
"(2, 'Li Si', 21);";
ret = sqlite3_exec(db, insert_sql, NULL, NULL, &err_msg);
if (ret != SQLITE_OK) {
printf("插入数据失败(可能主键重复):%s\n", err_msg);
sqlite3_free(err_msg);
} else {
printf("插入数据成功!\n");
}
// 5. 查询数据(查):调用回调函数处理结果
printf("\n===== 查询所有学生数据 =====");
const char *query_sql = "SELECT * FROM student;";
ret = sqlite3_exec(db, query_sql, query_callback, NULL, &err_msg);
if (ret != SQLITE_OK) {
printf("查询数据失败:%s\n", err_msg);
sqlite3_free(err_msg);
sqlite3_close(db);
return 1;
}
// 6. 更新数据(改):修改Li Si的年龄为22
const char *update_sql = "UPDATE student SET age = 22 WHERE name = 'Li Si';";
ret = sqlite3_exec(db, update_sql, NULL, NULL, &err_msg);
if (ret != SQLITE_OK) {
printf("\n更新数据失败:%s\n", err_msg);
sqlite3_free(err_msg);
} else {
printf("\n更新数据成功(Li Si年龄改为22)!\n");
}
// 7. 再次查询,验证更新结果
printf("\n===== 更新后的数据 =====");
ret = sqlite3_exec(db, query_sql, query_callback, NULL, &err_msg);
if (ret != SQLITE_OK) {
printf("查询数据失败:%s\n", err_msg);
sqlite3_free(err_msg);
sqlite3_close(db);
return 1;
}
// 8. 删除数据(删):删除id=1的学生
const char *delete_sql = "DELETE FROM student WHERE id = 1;";
ret = sqlite3_exec(db, delete_sql, NULL, NULL, &err_msg);
if (ret != SQLITE_OK) {
printf("\n删除数据失败:%s\n", err_msg);
sqlite3_free(err_msg);
} else {
printf("\n删除数据成功(删除id=1的学生)!\n");
}
// 9. 第三次查询,验证删除结果
printf("\n===== 删除后的数据 =====");
ret = sqlite3_exec(db, query_sql, query_callback, NULL, &err_msg);
if (ret != SQLITE_OK) {
printf("查询数据失败:%s\n", err_msg);
sqlite3_free(err_msg);
sqlite3_close(db);
return 1;
}
// 10. 关闭数据库
sqlite3_close(db);
printf("\n关闭数据库成功!\n");
return 0;
}步骤 2:代码说明与运行结果
关键逻辑解释
- 回调函数:
query_callback仅用于查询,自动接收每行数据,先打印列名,再打印每行值。 - 错误处理:每次调用
sqlite3_exec后检查返回值,若失败则打印err_msg并释放内存(避免泄漏)。 - 幂等操作:
CREATE TABLE IF NOT EXISTS确保表不存在时才创建,避免重复创建错误;插入数据若主键重复(如再次运行程序),会提示失败但不崩溃。
预期运行结果
打开数据库成功! 创建表成功(或表已存在)! 插入数据成功! ===== 查询所有学生数据 ===== id name age 1 Zhang San 20 2 Li Si 21 更新数据成功(Li Si年龄改为22)! ===== 更新后的数据 ===== id name age 1 Zhang San 20 2 Li Si 22 删除数据成功(删除id=1的学生)! ===== 删除后的数据 ===== id name age 2 Li Si 22 关闭数据库成功!
三、重点注意事项
- 内存释放:
sqlite3_exec输出的err_msg必须用sqlite3_free释放,否则会导致内存泄漏。 - 数据库关闭:所有操作完成后必须调用
sqlite3_close,若有未提交的事务,会自动回滚。 - 主键唯一性:插入数据时需确保主键(如
id)不重复,否则插入失败(案例中已处理该提示)。 - 数据类型:SQLite3 是弱类型数据库,定义的
INT/TEXT仅为提示,实际可存储任意类型,但建议按定义使用。
总结
到此这篇关于Linux环境下SQLite简单实现的文章就介绍到这了,更多相关Linux下SQLite实现内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
