SQLITE3
在开始之前先介绍一下什么是SQLite
数据库,SQLite
是一款开源的、嵌入式关系型数据库,SQLite
非常适合前途是产品,因为其没有独立运行的进程,它与服务的应用程序在应用程序的进程空间内共生共存。它的代码和应用程序的代码是在一起的或者说是嵌入其中,作为托管它的程序的一部分。
为什么学习数据库建议你先学习SQLite
数据库,特别是嵌入式开发的人员。因为SQLite
的作者都说过SQLite
是一款无论你使用的是什么操作系统,都能够在5分钟内完成,数据库的安装配置,以及创建自己的第一个数据库。
SQLite
?SQLite
不需要配置,这意味着不需要安装或管理。SQLite
数据库是存储在一个单一的跨平台的磁盘文件。SQLite
是非常小的,是轻量级的,完全配置时小于 400KiB
,省略可选功能配置时小于250KiB
。SQLite
是自给自足的,这意味着不需要任何外部的依赖。SQLite
事务是完全兼容 ACID 的,允许从多个进程或线程安全访问。SQLite
支持 SQL92
(SQL2
)标准的大多数查询语言的功能。SQLite
使用 ANSI-C 编写的,并提供了简单和易于使用的 API
。SQLite
可在 UNIX(Linux, Mac OS-X, Android, iOS
)和 Windows(Win32
, WinCE
, WinRT
)中运行 好了说了那么多,现在直接进入正题,进入 [地址]:https://www.sqlite.org/index.html 下载最新的SQLite
源码,按照源码中文档安装数据库,一下的代码都是在UBUNTU 16.04
上测试通过的代码 ,测试代码的git仓库见文末。
SQLite
命令 将命令按照操作的性质可以分为一下几种;
DDL
- 数据定义语言
CREATE |
创建一个新的表,一个表的视图,或者数据库中其他的对象 |
---|---|
ALTER |
修改数据库中某个已有的数据库对象,比如一个表 |
DROP |
删除整个表,或者表的视图,或者数据库中其他对象 |
DML
- 数据操作语言
INSERT |
创建一条记录 |
---|---|
UPDATE |
修改记录 |
DELETE |
删除记 |
DQL
- 数据查询语言
命令 | 描述 |
---|---|
SELECT |
从一个或者多个表中检索记录 |
SQLite
的一些简单的使用,以及命令可以参考 [地址]:https://www.runoob.com/sqlite/sqlite-tutorial.html$sqlite3 test.db #使用sqlite3打开一个数据库,如果数据库不存在就创建对应的数据库
.echo on # 在屏幕上打印执行的SQL语句
.mode column #以列的模式显示 结果
.headers on # 包含列名称
.nullvalue NULL # 将nulls打印成NULL
create [temp] table table_name (column_definitions [, constraints]);
#指定 temp说明创建的表是临时表,临时表只存活于当前会话,会话结束表会立即释放
lter table table{rename to name | add column column_def};
# alter table contacts add column email text not null default '' collate nocase;
select name from (select name, type_id from (select * from foods));
select heading from tables where predicate;
select * from dogs where color='purple' and grin= 'toothy';
# %可以与任一多个或者单个字符匹配,下划线可以与任一一个字符匹配
select id, name from foods where name like '%ac%p%';
select id, name from foods where name like '%ac%P%' and name not like '%Sch%';
limit
和offset
关键字限定结果集的大小和范围,limit
指定返回记录中的最大数量,offset
指定偏移的记录数。select * from food_types order by id limit 1 offset 1;
# 关键字offset在结果集中,跳过一行(Bakery),关键字limit限制最多返回一行(Cereal)
# order by使返回的结果按照某种排序进行输出-asc(默认的升序)或desc(降序)。
select * from foods where name like 'B%' order by type_id desc, name limit 10;
# limit和offset一起使用时,可以使用逗号代替offset
# 有些人可能认为这里的语法应该倒过来,在SQLite中,使用缩写时,offset总是优先limit,紧随limit关键字的值是offset 2 ,也要注意到,offset依赖于limit, 也就是说,可以只使用Limit不到offset但是反过来不行。
select * from foods where name like 'B%' order by type_id desc, name limit 1 offset 2;
select * from foods where name like 'B%' order by type_id desc, name limit 2, 1;
连接(join)是多表(关系)数据工作的关键,它是select命令的第一个操作,连接操作的结果作为输入,供select语句的其他部分(过滤)处理。
select foods.name, food_types_.name from foods, food_types where fods.type_id =food_types.id limit 10;
# 外链接相当于取两表相交的地方
select * from foods inner join food_types on foods.id = food_types.id;
select * from foods, food_types;
# 子查询就是子啊select语句又嵌套select语句。
select 1 in (1,2,3);
select count(*) from foods where type_id in (1,2);
select count(*) from foods where type_id in (select id from food_types where name='Bakery' or name='Cereal');
select name || case type_id
when 7 then ' is a drink '
when 8 then 'is a fruit'
when 9 then ' is junkfood'
when 13 then ' is seafood'
else null
end description
from foods
where description is not null
order by name
limit 10;
insert into table (column_list) values (value_list);
# insert into foods (nam, type_id) values ('Cinnamon Bobla', 1);
update table set update_list where predicate;
delete from table where predicate;
delete from foods where name = 'CHOCOLATE BOBKA';
/*
** Open a new database handle.
*/
//< 打开操作句柄
int sqlite3_open(
const char *zFilename, //< 文件名字
sqlite3 **ppDb //< 操作句柄
)
//< 返回UTF8编码的英文常见错误
/*
** Return UTF-8 encoded English language explanation of the most recent
** error.
*/
const char *sqlite3_errmsg(sqlite3 *db)
/*
** Execute SQL code. Return one of the SQLITE_ success/failure
** codes. Also write an error message into memory obtained from
** malloc() and make *pzErrMsg point to that message.
**
** If the SQL is a query, then for each row in the query result
** the xCallback() function is called. pArg becomes the first
** argument to xCallback(). If xCallback=NULL then no callback
** is invoked, even for queries.
*/
//< 执行SQL语句
int sqlite3_exec(
sqlite3 *db, /* The database on which the SQL executes */
const char *zSql, /* The SQL to be executed */
sqlite3_callback xCallback, /* Invoke this callback routine,回调函数,执行的SQL语句有输出时 */
void *pArg, /* First argument to xCallback() */
char **pzErrMsg /* Write error messages here */
)
/*
** Windows systems should call this routine to free memory that
** is returned in the in the errmsg parameter of sqlite3_open() when
** SQLite is a DLL. For some reason, it does not work to call free()
** directly.
**
** Note that we need to call free() not sqliteFree() here.
*/
void sqlite3_free(char *p){ free(p); }
/*
** The type for a callback function.
*/
//< 回调函数定义
typedef int (*sqlite3_callback)(void*,int,char**, char**);
/*
** A function to close the database.
**
** Call this function with a pointer to a structure that was previously
** returned from sqlite3_open() and the corresponding database will by closed.
**
** All SQL statements prepared using sqlite3_prepare() or
** sqlite3_prepare16() must be deallocated using sqlite3_finalize() before
** this routine is called. Otherwise, SQLITE_BUSY is returned and the
** database connection remains open.
*/
//< 关闭SQL句柄
int sqlite3_close(sqlite3 *);
实现创建数据表,向数据表中添加数据,并查询对应表格数据,使用回调函数打印出查询出的数据。
creat_db_datebase.c
#include
#include
#include
#include
/**
* @brief callback
* @note 回调函数,用于获取查看SQL语句返回数据
* @param *NotUsed:sqlite3_exec函数的第四个参数传入的数据
* @param argc: 数据的行数
* @param **argv: 列数据数组
* @param **azColName: 列标识符数组
* @retval
*/
static int callback(void *NotUsed, int argc, char **argv, char **azColName){
int i;
for(i=0; i<argc; i++){
printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
}
printf("\n");
return 0;
}
int main(int argc, char* argv[])
{
sqlite3 *db;
char *zErrMsg = 0;
int rc;
char *sql;
char sql_str[1024];
/* Open database */
//< 打开数据库文件,如果对应的数据库不存在就创建
rc = sqlite3_open("test.db", &db);
if( rc ){
fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
exit(0);
}else{
fprintf(stdout, "Opened database successfully\n");
}
/* Create SQL statement */
//< 建表语句定义
/* 创建主键 */ //"ID INT PRIMARY KEY NOT NULL,"
//< 表格不存在就创建表格,存在不重新创建,但是返回成功
sql = "CREATE TABLE IF NOT EXISTS class(" \
"ID INT PRIMARY KEY NOT NULL," \
"NAME TEXT NOT NULL," \
"AGE INT NOT NULL," \
"ADDRESS CHAR(50)," \
"SALARY REAL );";
/* Execute SQL statement */
//< 返回程序生成的执行的任何返回
rc = sqlite3_exec(db, sql, callback, 0, &zErrMsg);
if( rc != SQLITE_OK ){
fprintf(stderr, "SQL error: %s\n", zErrMsg);
sqlite3_free(zErrMsg);
}else{
fprintf(stdout, "Table created successfully\n");
}
memset(sql_str, 0, sizeof(sql_str));
//< replace 官网上很少说名,其他写SQLite数据库的文章也很少介绍,我这里理解的 replace就是
//< update与insert的合体,当存在记录的时候就相当于使用update 当记录不存在的时候就相当与使用insert
snprintf(sql_str, sizeof(sql_str), "replace into class"
"(ID, NAME, AGE, ADDRESS, SALARY)"
" values (%d, '%s', %d, '%s', %f)",
1, "alice", 18, "10.1.1.1", 100000.123
);
rc = sqlite3_exec(db, sql_str, callback, 0, &zErrMsg);
if( rc != SQLITE_OK ){
fprintf(stderr, "SQL error: %s\n", zErrMsg);
sqlite3_free(zErrMsg);
}else{
fprintf(stdout, "Table replace successfully\n");
}
memset(sql_str, 0, sizeof(sql_str));
//< 查询class表中的数据
memcpy(sql_str, "select * from class;", sizeof(sql_str));
rc = sqlite3_exec(db, sql_str, callback, 0, &zErrMsg);
if( rc != SQLITE_OK ){
fprintf(stderr, "SQL error: %s\n", zErrMsg);
sqlite3_free(zErrMsg);
}else{
fprintf(stdout, "Table created successfully\n");
}
sqlite3_close(db);
return 0;
}
衔接[SQLite数据库-数据表的创建,插入数据和查询数据]:https://blog.csdn.net/andrewgithub/article/details/100717099
上一篇文章讲述了,数据库的创建、数据的插入和删除,这里衔接上一篇文章主要讲述数据的删除。
删除数据,注意并不是删除一个数据表,只是删除一个数据表中的一个数据项;
creat_db_delete.c
代码仓库路径:https://github.com/zzu-andrew/linux-sys/tree/dfew/SQLite
#include
#include
#include
#include
static int callback(void *data, int argc, char **argv, char **azColName){
int i;
fprintf(stderr, "%s: ", (const char*)data);
for(i=0; i<argc; i++){
printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
}
printf("\n");
return 0;
}
int main(int argc, char* argv[])
{
sqlite3 *db;
char *zErrMsg = 0;
int rc;
char *sql;
char sql_str[512];
const char* data = "Callback function called";
/* Open database */
rc = sqlite3_open("test.db", &db);
if( rc ){
fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
exit(0);
}else{
fprintf(stderr, "Opened database successfully\n");
}
/* Create SQL statement */
//< 建表语句定义
/* 创建主键 */ //"ID INT PRIMARY KEY NOT NULL,"
//< 表格不存在就创建表格,存在不重新创建,但是返回成功
sql = "CREATE TABLE IF NOT EXISTS class(" \
"ID INT PRIMARY KEY NOT NULL," \
"NAME TEXT NOT NULL," \
"AGE INT NOT NULL," \
"ADDRESS CHAR(50)," \
"SALARY REAL );";
/* Execute SQL statement */
//< 返回程序生成的执行的任何返回
rc = sqlite3_exec(db, sql, callback, 0, &zErrMsg);
if( rc != SQLITE_OK ){
fprintf(stderr, "SQL error: %s\n", zErrMsg);
sqlite3_free(zErrMsg);
}else{
fprintf(stdout, "Table created successfully\n");
}
memset(sql_str, 0, sizeof(sql_str));
//< 插入一条,ID为2的数据
snprintf(sql_str, sizeof(sql_str), "replace into class"
"(ID, NAME, AGE, ADDRESS, SALARY)"
" values (%d, '%s', %d, '%s', %f)",
2, "alice", 18, "10.1.1.1", 100000.123
);
rc = sqlite3_exec(db, sql_str, callback, 0, &zErrMsg);
if( rc != SQLITE_OK ){
fprintf(stderr, "SQL error: %s\n", zErrMsg);
sqlite3_free(zErrMsg);
}else{
fprintf(stdout, "Table replace successfully\n");
}
memset(sql_str, 0, sizeof(sql_str));
//< 查询class表中的数据
fprintf(stdout, "----------------------------------------------------------!\n");
fprintf(stdout, "Before delete !!\n");
memcpy(sql_str, "select * from class;", sizeof(sql_str));
rc = sqlite3_exec(db, sql_str, callback, 0, &zErrMsg);
if( rc != SQLITE_OK ){
fprintf(stderr, "SQL error: %s\n", zErrMsg);
sqlite3_free(zErrMsg);
}else{
fprintf(stdout, "Table created successfully\n");
}
/* Create merged SQL statement */
//< 将 ID = 2的数据删除
fprintf(stdout, "----------------------------------------------------------!\n");
fprintf(stdout, "after delete !!\n");
sql = "DELETE from class where ID=2; " \
"SELECT * from class";
/* Execute SQL statement */
rc = sqlite3_exec(db, sql, callback, (void*)data, &zErrMsg);
if( rc != SQLITE_OK ){
fprintf(stderr, "SQL error: %s\n", zErrMsg);
sqlite3_free(zErrMsg);
}else{
fprintf(stdout, "Operation done successfully\n");
}
sqlite3_close(db);
return 0;
}
Opened database successfully
Table created successfully
Table replace successfully
----------------------------------------------------------!
Before delete !!
(null): ID = 1
NAME = alice
AGE = 18
ADDRESS = 10.1.1.1
SALARY = 100000.123
(null): ID = 2
NAME = alice
AGE = 18
ADDRESS = 10.1.1.1
SALARY = 100000.123
Table created successfully
----------------------------------------------------------!
# 数据表中 ID=2的数据项以被删除
after delete !!
Callback function called: ID = 1
NAME = alice
AGE = 18
ADDRESS = 10.1.1.1
SALARY = 100000.123
Operation done successfully
#include
#include
#include
static int callback(void *NotUsed, int argc, char **argv, char **azColName){
int i;
for(i=0; i<argc; i++){
printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
}
printf("\n");
return 0;
}
int main(int argc, char* argv[])
{
sqlite3 *db;
char *zErrMsg = 0;
int rc;
char *sql;
/********************第一步,打开数据库文件,获取数据库文件操作句柄*************************/
rc = sqlite3_open("test.db", &db);
if( rc ){
fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
exit(0);
}else{
fprintf(stderr, "Opened database successfully\n");
}
/********************第二步、定义数据操作语句***********************/
sql = "INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY) " \
"VALUES (1, 'Paul', 32, 'California', 20000.00 ); " \
"INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY) " \
"VALUES (2, 'Allen', 25, 'Texas', 15000.00 ); " \
"INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY)" \
"VALUES (3, 'Teddy', 23, 'Norway', 20000.00 );" \
"INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY)" \
"VALUES (4, 'Mark', 25, 'Rich-Mond ', 65000.00 );";
/********************第三步、执行建表语句建立数据表**********************/
rc = sqlite3_exec(db, sql, callback, 0, &zErrMsg);
if( rc != SQLITE_OK ){
fprintf(stderr, "SQL error: %s\n", zErrMsg);
sqlite3_free(zErrMsg);
}else{
fprintf(stdout, "Records created successfully\n");
}
sqlite3_close(db);
return 0;
}
#include
#include
#include
static int callback(void *data, int argc, char **argv, char **azColName){
int i;
fprintf(stderr, "%s: ", (const char*)data);
for(i=0; i<argc; i++){
printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
}
printf("\n");
return 0;
}
//FIXME:
// TODO:
int main(int argc, char* argv[])
{
sqlite3 *db;
char *zErrMsg = 0;
int rc;
char *sql;
const char* data = "Callback function called";
/* Open database */
rc = sqlite3_open("test.db", &db);
if( rc ){
fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
exit(0);
}else{
fprintf(stderr, "Opened database successfully\n");
}
/* Create merged SQL statement */
sql = "UPDATE COMPANY set SALARY = 25000.00 where ID=1; " \
"SELECT * from COMPANY";
/* Execute SQL statement */
rc = sqlite3_exec(db, sql, callback, (void*)data, &zErrMsg);
if( rc != SQLITE_OK ){
fprintf(stderr, "SQL error: %s\n", zErrMsg);
sqlite3_free(zErrMsg);
}else{
fprintf(stdout, "Operation done successfully\n");
}
sqlite3_close(db);
return 0;
}
//TODO: 部分的sqlite版本中,对于主键为null使的处理方式不同
* 1.null不等于任何值,包括它自身,当主键为null时,会导致插入的数据会持续增长,因为数据数据库插入数据的时候
* 找不到相同的主键组合(NULL != NULL)
* 2.将主键为null是认为是相同的如有三个主键的组合(1, 2, null) == (1, 2, null)
*
* 处理方式不同,这里处理函数执行之后看到的结果是不一样的。
/*
+--------+ +-------+ +--------------+ +---------------+
| B-tree | --> | Pager | --> | os | --> | Database File |
+--------+ +-------+ +--------------+ +---------------+
|
|
v
+--------------+
| Journal File |
+--------------+
*/
#include
#include
#include
#include
#define create_test_table "CREATE TABLE test_not_null(" \
"id integer," \
"idx1 integer," \
"chan integer," \
"name TEXT NOT NULL," \
"age INT NOT NULL," \
"address CHAR(50)," \
"salary REAL,"\
"primary key(id, idx1, chan));"
#define create_test_null_table "CREATE TABLE test_null(" \
"id integer," \
"idx1 integer," \
"chan integer," \
"name TEXT NOT NULL," \
"age INT NOT NULL," \
"address CHAR(50)," \
"salary REAL,"\
"primary key(id, idx1, chan));"
static int callback(void *NotUsed, int argc, char **argv, char **azColName){
int i;
for(i=0; i<argc; i++){
printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
}
printf("\n");
return 0;
}
//TODO: 部分的sqlite版本中,对于主键为null使的处理方式不同
/***
* 1.null不等于任何值,包括它自身,当主键为null时,会导致插入的数据会持续增长,因为数据数据库插入数据的时候
* 找不到相同的主键组合(NULL != NULL)
* 2.将主键为null是认为是相同的如有三个主键的组合(1, 2, null) == (1, 2, null)
*
* 处理方式不同,这里处理函数执行之后看到的结果是不一样的。
* */
int main(int argc, char* argv[])
{
sqlite3 *db;
char *zErrMsg = 0;
int rc;
char sql_str[512];
int i = 0;
int j = 0;
/* Open database */
//< 如果文件存在就打开数据库文件
//< 如果文件不存在就打开一个数据库,等有实际操作了在创建该数据库文件
rc = sqlite3_open("test.db", &db);
if( rc ){
fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
exit(0);
}else{
fprintf(stdout, "Opened database successfully\n");
}
/***
* 创建含有创建主键全不为null的表
*
* */
rc = sqlite3_exec(db, create_test_table, callback, 0, &zErrMsg);
if( rc != SQLITE_OK ){
fprintf(stderr, "SQL test: %s\n", zErrMsg);
sqlite3_free(zErrMsg);
}else{
fprintf(stdout, "Table created successfully\n");
}
/***
* 创建用于测试主键中含有null时的表
*
* */
rc = sqlite3_exec(db, create_test_null_table, callback, 0, &zErrMsg);
if( rc != SQLITE_OK ){
fprintf(stderr, "SQL test: %s\n", zErrMsg);
sqlite3_free(zErrMsg);
}else{
fprintf(stdout, "Table created successfully\n");
}
for (j = 0; j < 2; j ++)
{
/**
* @brief 循环写入主键中没有null的数据
*
*/
for (i = 0; i < 30; i++)
{
memset(sql_str, 0, sizeof(sql_str));
snprintf(sql_str, sizeof(sql_str),
"replace into test_not_null(id, idx1, chan, name, age)"
"values(%d, %d, %d, '%s', %d);",
i, 2, 3, "Mack", i);
rc = sqlite3_exec(db, sql_str, callback, 0, &zErrMsg);
if( rc != SQLITE_OK ){
fprintf(stderr, "SQL error: %s\n", zErrMsg);
sqlite3_free(zErrMsg);
}else{
fprintf(stdout, "Table created successfully\n");
}
}
/**
* @brief 循环写入主键中含有null的数据表
*
*/
for (i = 0; i < 30; i++)
{
memset(sql_str, 0, sizeof(sql_str));
snprintf(sql_str, sizeof(sql_str),
"replace into test_null(id, idx1, name, age)"
"values(%d, %d, '%s', %d);",
i, 2, "Mack", i);
rc = sqlite3_exec(db, sql_str, callback, 0, &zErrMsg);
if( rc != SQLITE_OK ){
fprintf(stderr, "SQL error: %s\n", zErrMsg);
sqlite3_free(zErrMsg);
}else{
fprintf(stdout, "Table created successfully\n");
}
}
}
//< 查询,test_not_null表中的数据
memcpy(sql_str, "select * from test_not_null;", sizeof(sql_str));
rc = sqlite3_exec(db, sql_str, callback, 0, &zErrMsg);
if( rc != SQLITE_OK ){
fprintf(stderr, "SQL error: %s\n", zErrMsg);
sqlite3_free(zErrMsg);
}else{
fprintf(stdout, "Table created successfully\n");
}
//< 查询,test_null表中的数据
memcpy(sql_str, "select * from test_null;", sizeof(sql_str));
rc = sqlite3_exec(db, sql_str, callback, 0, &zErrMsg);
if( rc != SQLITE_OK ){
fprintf(stderr, "SQL error: %s\n", zErrMsg);
sqlite3_free(zErrMsg);
}else{
fprintf(stdout, "Table created successfully\n");
}
sqlite3_close(db);
return 0;
}
#include
#include
#include
#include
/****
* */
typedef struct school
{
int teacher_num;
int student_num;
int bicycle_num;
}SCHOOL;
/**
* @brief callback
* @note 回调函数,用于获取查看SQL语句返回数据
* @param *NotUsed:sqlite3_exec函数的第四个参数传入的数据
* @param argc: 数据的行数
* @param **argv: 列数据数组
* @param **azColName: 列标识符数组
* @retval
*/
static int callback(void *NotUsed, int argc, char **argv, char **azColName){
int i;
SCHOOL school_temp;
for(i=0; i<argc; i++){
if (0 == strcmp("school", azColName[i]))
{
memcpy(&school_temp, argv[i], sizeof(school_temp));
printf("teacher number = [%d], student number = [%d], bicycle number = [%d]\n\n",
school_temp.teacher_num, school_temp.student_num, school_temp.bicycle_num);
}
else
{
printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
}
}
printf("\n");
return 0;
}
int main(int argc, char **argv)
{
sqlite3 *db;
char *zErrMsg = 0;
int rc;
char *sql;
char sql_str[1024];
SCHOOL ZZU;
sqlite3_stmt *stmt;
const char* tail;
memset(&ZZU, 0, sizeof(ZZU));
ZZU.teacher_num = 35000;
ZZU.student_num = 90000;
ZZU.bicycle_num = 20000;
/* Open database */
//< 打开数据库文件,如果对应的数据库不存在就创建
rc = sqlite3_open("test.db", &db);
if( rc ){
fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
exit(0);
}else{
fprintf(stdout, "Opened database successfully\n");
}
/* Create SQL statement */
//< 建表语句定义
/* 创建主键 */ //"ID INT PRIMARY KEY NOT NULL,"
//< 表格不存在就创建表格,存在不重新创建,但是返回成功
sql = "CREATE TABLE IF NOT EXISTS test_blob(" \
"id INT," \
"NAME TEXT," \
"school blob," \
"ADDRESS CHAR(50)," \
"primary key(ID));";
/* Execute SQL statement */
//< 返回程序生成的执行的任何返回
rc = sqlite3_exec(db, sql, callback, 0, &zErrMsg);
if( rc != SQLITE_OK ){
fprintf(stderr, "SQL error: %s\n", zErrMsg);
sqlite3_free(zErrMsg);
}else{
fprintf(stdout, "Table created successfully\n");
}
memset(sql_str, 0, sizeof(sql_str));
snprintf(sql_str, sizeof(sql_str), "replace into test_blob"
"(id, NAME, school, ADDRESS)"
" values (%d, '%s', ?, '%s')",
1, "ZZU", "10.1.1.1");
rc = sqlite3_prepare(db, sql_str, (int)strlen(sql), &stmt, &tail);
if(rc != SQLITE_OK) {
fprintf(stderr, "Error: %s\n", tail);
}
/***
* int sqlite3_bind_blob(
sqlite3_stmt *pStmt, //stmt描述语句
int i, //< 第几个绑定参数(位置参数),也就是第几个问号,其中问号后面可以指定位置参数
const void *zData, //< 绑定的参数数据
int nData, //< 二进制数据的大小
void (*xDel)(void*) //< 数据的类型,说明需不需slqite对传入的数据进行管理
)
*/
sqlite3_bind_blob(stmt, 1, (void *)&ZZU, sizeof(ZZU), SQLITE_STATIC);
//< 执行语句
sqlite3_step(stmt);
sqlite3_finalize(stmt);
//< 查询class表中的数据
memcpy(sql_str, "select * from test_blob;", sizeof(sql_str));
rc = sqlite3_exec(db, sql_str, callback, 0, &zErrMsg);
if( rc != SQLITE_OK ){
fprintf(stderr, "SQL error: %s\n", zErrMsg);
sqlite3_free(zErrMsg);
}else{
fprintf(stdout, "get test_blob sucess!!\n");
}
sqlite3_close(db);
return 0;
}
代码仓库地址:https://github.com/zzu-andrew/linux-sys/tree/dfew/SQLite