玳瑁的嵌入式日记D33-0908(SQL数据库)

发布于:2025-09-09 ⋅ 阅读:(15) ⋅ 点赞:(0)

一、SQLite3 数据库创建与基础操作

1. 数据库创建

通过命令行工具快速创建并进入 SQLite3 数据库:

  1. 创建数据库文件:touch xxx.db(xxx 为自定义数据库名称,如 test.db
  2. 进入数据库交互环境: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:筛选条件(支持 ><=ANDORNOT,以及通配符 % 匹配任意字符、_ 匹配单个字符)
  • 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;
}

网站公告

今日签到

点亮在社区的每一天
去签到