sqlite3

sqlite3

最近工作中用到了数据库,具体使用是,打开数据库->进行数据库操作->关闭数据库

打开数据库

sqlite3有三个打开数据库的函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
int sqlite3_open
(
const char *filename, /* Database filename (UTF-8) */
sqlite3 **ppDb /* OUT: SQLite db handle */
);

int sqlite3_open16
(
const void *filename, /* Database filename (UTF-16) */
sqlite3 **ppDb /* OUT: SQLite db handle */
);

int sqlite3_open_v2
(
const char *filename, /* Database filename (UTF-8) */
sqlite3 **ppDb, /* OUT: SQLite db handle */
int flags, /* Flags */
const char *zVfs /* Name of VFS module to use */
);

其中sqlite3_open()和sqlite3_open16()都是可读可写打开数据库,如果数据库不存在,则创建数据库;它们的区别在于数据库名称的编码,前者是UTF-8,后者是UTF-16

sqlite3_open_v2()则是sqlite3_open()的升级,它可以通过flags参数,指定打开数据库的模式

关闭数据库

关闭数据库比较简单直接使用sqlite3_close(sqlite3 *db)就可以了,关于sqlite3_close_v2()我没有深入了解

关于打开和关闭数据库,我在在项目中是这样使用的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
int result;
sqlite3 *db;

if (access(FILE, F_OK) != 0)
{
result = sqlite3_open_v2(FILE, &db, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL);
}
else
{
result = sqlite3_open_v2(FILE, &db, SQLITE_OPEN_READWRITE, NULL);
}

if (result != SQLITE_OK)
{
printf("error:%s\n", sqlite3_errmsg(db));
sqlite3_close(db);
}

判断数据库是否存在,如果不存在则创建,并以可读可写模式打开;如果存在则直接以可读可写模式打开(注:由于我有一个全局变量保存SQLite db handle所以没有直接关闭数据库)

执行SQLite语句

执行SQL语句需要用到sqlite3_exec()函数,函数原型如下:

1
2
3
4
5
6
7
8
int sqlite3_exec
(
sqlite3* pDB, /* sqlite3句柄 */
const char* sql, /* 被执行的 SQL 语句 */
int (*callback)(void*,int,char**,char**), /* 执行/查询回调函数 */
void* pvoid, /* 传递给回调函数的第一个参数 */
char**errmsg /* 错误输出信息 */
);

sqlite3_exec()接口执行多条以”; “分隔的SQL语句。如果回调函数不为 NULL, 则它对每一个行查询结果都会调用该回调函数. 如果没有回调函数被指定, sqlite3_exec() 只是简单地忽略查询结果

当在执行该SQL语句发生错误时, 执行将发生中断, 并且后面的语句也全部被忽略

如果 errmsg 参数不为空任何错误信息将会被写进由 sqlite3_malloc() 得到的的内存空间中, 即 errmsg 指向的内存。为了避免内存泄漏, 应用程序应该在不需要该错误信息后立即调用 sqlite3_free() 释放该内存空间。如果 errmsg 参数不为 NULL, 并且没有错误发生, errmsg 被设置为 NULL

例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
do
{
result = sqlite3_exec(db, db_cmd_buf, 0, 0, 0);
} while (result == SQLITE_BUSY);

if (result == SQLITE_OK)
{
return 0;
}
else
{
printf("error:%s\n", sqlite3_errmsg(db));
}

db_cmd_buf里放的就是我们需要执行的SQL语句

SQLite语句

SQLite 是不区分大小写的,但也有一些命令是大小写敏感的,比如 GLOB 和 glob 在 SQLite 的语句中有不同的含义

下面是在C/C++ 中传递给sqlite3_exec()函数的几类SQLite语句:

创建表

创建表的语法如下:

1
2
3
4
5
6
7
8
CREATE TABLE table_name
(
column1 datatype PRIMARY KEY(one or more columns),
column2 datatype,
column3 datatype,
.....
columnN datatype,
);

CREATE TABLE 是告诉数据库系统创建一个新表的关键字。CREATE TABLE 语句后跟着表的唯一的名称或标识

删除表

删除表的语法如下:

1
DROP TABLE table_name;

添加数据

添加数据语句有两种基本语法,如下所示

1
2
3
INSERT INTO TABLE_NAME [(column1, column2, column3,...columnN)] VALUES (value1, value2, value3,...valueN);

INSERT INTO TABLE_NAME VALUES (value1,value2,value3,...valueN);

在这里,column1, column2,…columnN 是要插入数据的表中的列的名称。如果要为表中的所有列添加值,您也可以不需要在 SQLite 查询中指定列名称。但要确保值的顺序与列在表中的顺序一致

WHERE AND OR

SQLite的 WHERE 子句用于指定从一个表或多个表中获取数据的条件。

如果满足给定的条件,即为真(true)时,则从表中返回特定的值。您可以使用 WHERE 子句来过滤记录,只获取需要的记录。

WHERE 子句不仅可用在 SELECT 语句中,它也可用在 UPDATE、DELETE 语句中,等等

1
2
SQLite 语句 WHERE [condition1] AND [condition2]...AND [conditionN];
SQLite 语句 WHERE [condition1] OR [condition2]...OR [conditionN];

删除数据

SQLite 的 DELETE 查询用于删除表中已有的记录

1
2
3
DELETE FROM table_name

DELETE FROM table_name WHERE [condition];

更新数据

SQLite 的 UPDATE 查询用于修改表中已有的记录。可以使用带有 WHERE 子句的 UPDATE 查询来更新选定行,否则所有的行都会被更新。

1
UPDATE table_name SET column1 = value1, column2 = value2...., columnN = valueN WHERE [condition];

查找数据

SQLite 的 SELECT 语句用于从 SQLite 数据库表中获取数据,以结果表的形式返回数据。这些结果表也被称为结果集。

1
2
3
4
5
SELECT column1, column2, columnN FROM table_name;

SELECT * FROM table_name;

SELECT * FROM table_name WHERE [condition];
  • column1, column2…是表的字段,他们的值即是要获取的
  • *代表所有字段

总结

此次完成的工作是完成Traffic service:从modem获取lte流量,创建定时器计算每天每月每年的数据,并保存到数据库中

数据库部分,主要完成一个traffic_db_new_command_buffer()函数来根据不同的需求返回不同的语句,然后调用sqlite3_exec()函数执行,最后在回调函数中查询结果

贴出traffic_db_new_command_buffer()函数部分代码仅供参考:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
char *traffic_db_new_command_buffer(COMMAND_TYPE traffic_cmd_type, TABLE_TYPE table, ITEM_INFO *traffic_info, char *select_tag, char *where_tag)
{
char *db_cmd_buff;
size_t cmd_buff_sizes = 512;
int i = 0;
TABLE_INFO *ptaffic_table_info;
db_cmd_buff = malloc(cmd_buff_sizes + 1);

if (db_cmd_buff != NULL)
{
switch (traffic_cmd_type)
{
case SELECT_COUNT_FROM:
sprintf(db_cmd_buff, "SELECT count(*) FROM %s", ptaffic_table_info->table_name);
return db_cmd_buff;

case ELECT_COUNT_FROM_WHERE:
sprintf(db_cmd_buff, "SELECT count(*) FROM %s WHERE %s;", ptaffic_table_info->table_name, where_tag);
return db_cmd_buff;

case SELECT_FROM_WHERE:
sprintf(db_cmd_buff, "SELECT * FROM %s WHERE %s;", ptaffic_table_info->table_name, where_tag);
return db_cmd_buff;

case SELECT_FROM:
sprintf(db_cmd_buff, "SELECT * FROM %s ;", ptaffic_table_info->table_name);
return db_cmd_buff;

case DELETE_FROM:
sprintf(db_cmd_buff, "DELETE from %s;", ptaffic_table_info->table_name);
return db_cmd_buff;

case DELETE_FROM_WHERE:
sprintf(db_cmd_buff, "DELETE from %s WHERE %s;", ptaffic_table_info->table_name, where_tag);
return db_cmd_buff;

default:
break;
}
free(db_cmd_buff);
}
return NULL;
}

sqlite3
https://carl-5535.github.io/2021/06/30/工作总结/sqlite3/
作者
Carl Chen
发布于
2021年6月30日
许可协议