IMPORTANT

此文档仍需调整补充。

Info

名词释义

  • 元素属性:一个具体事物的所有属性;将属性罗列出来,可以称为一个项目;在数据库中,一个元素占用一行;
  • :一个属性;是不可再分割的具有原子性的属性名称标识;在数据库中,一个键占用一列,可将其称为列键;根据以上所述,使用多列键就能表示这一个具体事物的所有属性;
  • 键值:一个属性的值;更具体地说,是一个具体事物的一个属性的值。

示例:

idnamescore
1Yuki21
2Natsu13
3Roger16

在以上表格中,每一行被称为一个项目 / 一个元素;

每一列的头部被称为键名 / 属性;

每一列头部之后的值被称为键值 / 属性值。

了解 SQL 基本语句

创建一个表

必须要先连接到一个数据库。

可使用 sqlite3 (path_to_database).db 创建数据库;若 sqlite 运行在终端,可使用 .open (name).db 连接或创建数据库。

CREATE TABLE [(database_name).]<table_name> (
	<key_name>		<type>		[properties],
    ...
);

解释

  • [(database_name).] 仅在连接到多个数据库时需要指定;
  • <type> 指定此键的数据类型,[properties] 指定此键的约束属性;这两个参数整体上不分先后;
  • 声明一个键以后,使用 , 分隔;
  • 指定字符类型时,应声明长度:char(byte_count)
  • 在一个键声明末尾处可添加 DEFAULT <value> 来设置此键在未设置值时使用的默认值;
  • 要设置主键自增,需设置其类型和属性为 INTEGER AUTOINCREMENT

为表添加新的行

表必须已存在,行主键不能已存在。

INSERT INTO <table_name> [<key1>, [key2], ...]
VALUES (<key1_val>, [key2_val], ...),
...
;

解释

  • 指定的键必须在表内存在,键可以无序或不全,但设置了 NOT NULLPRIMARY KEY 约束的键值不能为空;
  • VALUES () 的键值顺序是根据表名之后键的顺序确定的;
  • 表名后的键可以省略,VALUES () 将使用创建表时给出的键顺序,但此时 VALUE () 给出的值必须和键数量相同;可以使用 DEFAULT 代替值,或用 NULL 代替自增主键或可空值;
  • 可以同时添加多行,VALUES () 之间使用 , 分隔;
  • 可以使用 SELECT 从其他表将查询结果作为新行添加。

修改指定行的列数据

UPDATE <table_name>
SET <key> = <key_val>
WHERE <key> IS <key_val> 

设置依赖库

Info

设置依赖库的方法仅适用于 Debian / Ubuntu。

通过 apt 安装包管理器下载 SQLite 库。

apt install sqlite3 libsqlite3-dev

安装后,导入 sqlite3.h 即可使用;在编译/链接项目前,需添加 -lsqlite3 参数指定库以完成链接,此参数需要在指定的编译源文件之后。

SQLite 的函数异常处理

异常处理 Macro

  • #define SQLITE_OK 0
  • #define SQLITE_DONE 101
  • define SQLITE_ROW 102

输出异常消息

const char *sqlite3_errmsg(sqlite3*)

参数

数据库对象的指针。

返回值

此数据库的可读状态消息。

函数及用法

使用以下函数,需要导入 sqlite3.h

Info

在数据库,常将成功打开的一个数据库称为已连接的数据库

连接到数据库

声明一个数据库对象指针 sqlite3 *,然后作为引用传递给参数2;如果此数据库不存在将会创建。

int sqlite3_open(const char *filename, sqlite3 **ppDb)

参数

  1. SQLite 数据库文件的路径(常为 *.db);
  2. 如果数据库连接成功,通过此指针返回打开的数据库。

返回值

表示数据库连接状态的整型值。如果连接成功,返回0 (SQLITE_OK);其他情况返回非0值,状态消息会写入参数2的数据库对象。

从数据库断开连接

结束使用数据库时,应当将其关闭。

sqlite3_close(sqlite3* database)

运行 SQL 语句

SQLITE_API int sqlite3_exec(
  sqlite3*,                                  /* An open database */
  const char *sql,                           /* SQL to be evaluated */
  int (*callback)(void*,int,char**,char**),  /* Callback function */
  void *,                                    /* 1st argument to callback */
  char **errmsg                              /* Error msg written here */
)

参数

  1. 已连接的数据库对象指针;

  2. 要运行的 SQL 语句;

  3. 处理 SQL 运行结果的回调函数,每一行返回结果都将调用一次此函数。此回调函数的结构如下:

    int callback(void *data, int argc, char **argv, char **azColName)

    参数

    1. 来自 sqlite3_exec() 第4个参数的数据起址;
    2. 此行的列数;
    3. 此行逐列数据的字符串数组;
    4. 列名称字符串数组。

    返回值

    如果正确获取数据,此函数必须返回0;其他返回值会使 sqlite3_exec() 的运行中止并返回非0值。

    Info

    仅查询语句等会返回结果的 SQL 语句才会使此回调函数被调用。

  4. 要传递给回调函数第1个参数的数据起址;

  5. 存储异常消息字符串的指针,使用完成后应使用 sqlite3_free() 释放

返回值

如果 SQL 语句运行成功,返回0 (SQLITE_OK);其他情况返回非0值,应通过第5个参数 errmsg 获取可读异常信息。

[进阶] 注册 SQL 预处理语句

设置数据库的预处理语句,以便于后续添加新的行元素;预处理语句相比直接运行 SQL 数据插入语句能够带来更好的性能与安全性。

int sqlite3_prepare_v2(
  sqlite3 *db,            /* Database handle */
  const char *zSql,       /* SQL statement, UTF-8 encoded */
  int nByte,              /* Maximum length of zSql in bytes. */
  sqlite3_stmt **ppStmt,  /* OUT: Statement handle */
  const char **pzTail     /* OUT: Pointer to unused portion of zSql */
)

参数

  1. 已连接的数据库指针;
  2. 要运行的 SQL 预处理语句;
  3. 要运行的 SQL 预处理语句的长度,传入-1以自动计算(到达 \0 时停止);
  4. 输出的 SQL 预处理语句句柄指针,后续绑定函数需要使用此指针,并向此指针按序逐个传递行值;
  5. 运行后,未使用的 SQL 列键。

返回值

如果此 SQL 预处理语句注册成功,返回0 (SQLITE_OK);其他情况返回非0值。

Info

SQL 预处理语句的书写

设置预处理语句的关键是正确设置占位符(aka. 参数),占位符就是告诉计算机如何识别传入参数的类型和位置。可供使用的占位符有以下形式:

  • 位置占位符 ? 按顺序逐个识别对应的目标键名。 示例1:

    INSERT INTO a_table(id, user_name, score) VALUES(?, ?, ?);

    示例2:

    SELECT * FROM a_table WHERE score > VALUES(?);
  • 命名占位符(同名占位符):<key> | @<key> | $<key> 使用此方法可重排键顺序。 示例:

    INSERT INTO a_table(id, user_name, score) VALUES(:user_name, @id, $score);
  • 自动编号占位符 传入的值无需考虑顺序。

    SELECT * FROM a_table WHERE id IN (?, ?, ?);

[进阶] 参数绑定类函数

注册 SQL 预处理语句后,用参数绑定类函数逐个设置新行元素的列值,以实现最终插入一个新行元素。

int sqlite3_bind_int(sqlite3_stmt*, int /* Position */, int)
int sqlite3_bind_double(sqlite3_stmt*, int, double)
int sqlite3_bind_text(sqlite3_stmt*, int, const char*, int, void(*)(void*))

参数

  1. 已注册的 SQL 预处理语句对象指针,来自 sqlite3_prepare_*()
  2. 目标列键在预处理语句内的所在位置,从1开始计数;
  3. 列值;
  4. [仅字符串绑定] 列值是字符串时,字符串的字节数,传入-1以自动计算(到达 \0 时停止);
  5. [仅字符串绑定] 设置如何处理传入参数2的内存,可用的值有: SQLITE_STATIC 传入参数2的值是静态分配的,SQLite 将不会处理; SQLITE_TRANSIENT 传入参数2的值是动态分配的,SQLite 会立刻复制此字符串; <自定回调函数以释放> 调用用户指定的回调函数,以释放传入参数2的对象。

返回值

如果这个参数绑定成功,返回0 (SQLITE_OK);其他情况返回非0值。

[进阶] 运行预处理语句

在绑定好一行元素的参数后,或者设置好查询后,运行预处理语句以读取或写入到数据库。

int sqlite3_step(sqlite3_stmt*)

参数

已注册的 SQL 预处理语句对象指针。

返回值

如果一行新元素写入成功,返回101 (SQLITE_DONE);如果查询到一行元素,返回100 (SQLITE_ROW);其他情况的返回值均视为异常。

[进阶] 释放预处理语句

预处理语句不再需要使用时,应将其释放。

int sqlite3_finalize(sqlite3_stmt *pStmt)

参数

已注册的 SQL 预处理语句对象指针。

返回值

如果此 SQL 预处理语句完成释放,返回0 (SQLITE_OK);其他情况返回非0值。,