Linux下利用c/c++使用sqlite
Posted Overboom
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Linux下利用c/c++使用sqlite相关的知识,希望对你有一定的参考价值。
参考链接:
https://blog.csdn.net/u012351051/article/details/90382391
https://blog.csdn.net/no_sying_nothing/article/details/52518822
https://cloud.tencent.com/developer/article/1018696
1. 安装sqlite
下载连接:https://www.sqlite.org/snapshot/sqlite-snapshot-202105251610.tar.gz
1> 解压
2>./configure
3> make
4> make install
2. sqlite常用的三个操作API
1、sqlite3_open(const char* filename, sqlite3 **ppDb);
2、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 */
);
sqlite3* : open 打开的数据库
const char* sql, : 执行的sql功能语句
*callback, : sql语句对应的回调函数
void* data, : 传递给回调函数的 指针参数
char **errmsq : 错误信息
3、sqlite3_close(sqlite3*)
3. sqlite3_exec的回调函数 callback
typedef int(*sqlite_callback)(void* para, int columenCount, char** columnValue, char** columnName);
参数:
para : 由sqlite3_exec传入的参数指针【第四个参数】,或者说是指针参数
columnCount: 查询到的这一条记录由多少个字段(多少列)
columnValue : 该参数是双指针,查询出来的数据都保存在这里,它是一个1维数组,每一个元素都是一
个char*,是一个字段内容,所以这个参数就可以不是单字节,而是可以为字符串等不定
长度的数值,用字符串表示,以'\\0'结尾。
columnName : 该参数是双指针,语columnValue是对应的,表示这个字段的字段名称,
返回 : 执行成果则返回SQLITE_OK,否则返回其他值
这里面有几个地方容易理解错,回调函数的参数一定是 sql功能命令执行结果的进一步处理,其中para好理解,就是sqlite3_exec传递的参数,
columnCount:表示sql功能结果的“字段”,也就是“列”的个数,没错,就是“列”的个数。
另外需要特别注意的是:回调函数多数时候不是执行1次,而是会循环执行n次,当我们使用select进行sql功能时,往往输出的结果会是 多行,那么 有n行,就会执行n次的 回调函数。举例如下:
#include <stdio.h>
#include <stdlib.h>
#include <sqlite3.h>
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;
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 */
sql = "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;
}
这个数据库中表的内容如下(这里照搬了https://www.runoob.com/sqlite/sqlite-c-cpp.html 中的例子):
"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 );";
所以执行的结果:
Opened database successfully
Callback function called: ID = 1
NAME = Paul
AGE = 32
ADDRESS = California
SALARY = 20000.0
Callback function called: ID = 2
NAME = Allen
AGE = 25
ADDRESS = Texas
SALARY = 15000.0
Callback function called: ID = 3
NAME = Teddy
AGE = 23
ADDRESS = Norway
SALARY = 20000.0
Callback function called: ID = 4
NAME = Mark
AGE = 25
ADDRESS = Rich-Mond
SALARY = 65000.0
Operation done successfully
可以看出来,由于sql命令行为 select* from COMPANY,该命令会将表中所有信息都输出,总共5个字段(列),包含4条信息(行),所以这个回调函数会被执行4次,理解这个逻辑,非常重要。
而且回调函数的后两个参数是 双指针 ,也就是 指针的指针,包含了2层的指向,里层的 指向是 对应具体的数据指针,外层的指向则是 数据指针序号,也可以理解成 “列”索引。我们通过这两个指针能够进一步 编写 自定义功能代码。
4. 打开数据库并创建表
#include<stdio.h>
#include<sqlite3.h>
// 暂时先不管
static int callback(void *NotUsed, int argc, char **argv, char **azColName)
{
int i = 0;
for(i = 0; i < argc; i++)
{
printf("%s = %s\\n",azColName[i], argv[i]?argv[i]:"NULL");
}
printf("\\n");
return 0;
}
int main()
{
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);
return -1;
}
else
{
fprintf(stderr,"open database succeddfully\\n");
}
sql = "create table company(ID INT PRIMARY KEY NOT NULL, NAME TEXT NOT NULL, AGE TEXT NOT NULL, ADDRESS CHAR(50))";
rc = sqlite3_exec(db, sql, callback, 0, &zErrMsg); // 执行上面sql中的命令
if(SQLITE_OK != rc)
{
fprintf(stderr, "SQL error: %s\\n", zErrMsg);
}
else
{
fprintf(stdout, "create table successfully\\n");
}
sqlite3_close(db);
return 0;
}
运行:需要链接sqlite3库,下面的其他操作也是如此。
gcc sqlite3test.c -o create -l sqlite3
5. 插入数据
sql语法:
insert into + 表名 (列1, 列2, ...,列n)values(对应每列的值)
#include<stdio.h>
#include<sqlite3.h>
static int callback(void *NotUsed, int argc, char **argv, char **azColName)
{
int i = 0;
for(i = 0; i < argc; i++)
{
printf("%s = %s\\n",azColName[i], argv[i]?argv[i]:"NULL");
}
printf("\\n");
return 0;
}
int main()
{
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);
return -1;
}
else
{
fprintf(stderr,"open database succeddfully\\n");
}
// sql = "create table company(ID INT PRIMARY KEY NOT NULL, NAME TEXT NOT NULL, AGE TEXT NOT NULL, ADDRESS CHAR(50))";
sql = "insert into company(ID, NAME, AGE, ADDRESS) values(1, 'Paul', 25, 'USA');\\
insert into company(ID, NAME, AGE, ADDRESS) values(2, 'James', 28, 'JAP');\\
insert into company(ID, NAME, AGE, ADDRESS) values(3, 'Yao', 30, 'CHA');\\
insert into company(ID, NAME, AGE, ADDRESS) values(4, 'kobe', 38, 'USA');";
rc = sqlite3_exec(db, sql, callback, 0, &zErrMsg);
if(SQLITE_OK != rc)
{
fprintf(stderr, "SQL error: %s\\n", zErrMsg);
}
else
{
fprintf(stdout, "insert table successfully\\n");
}
sqlite3_close(db);
return 0;
}
6. 查询数据:
#include<stdio.h>
#include<sqlite3.h>
static int callback(void *NotUsed, int argc, char **argv, char **azColName)
{
int i = 0;
for(i = 0; i < argc; i++)
{
printf("%s = %s\\n",azColName[i], argv[i]?argv[i]:"NULL");
}
printf("\\n");
return 0;
}
int main()
{
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);
return -1;
}
else
{
fprintf(stderr,"open database succeddfully\\n");
}
sql = "select * from company;";
rc = sqlite3_exec(db, sql, callback, 0, &zErrMsg);
if(SQLITE_OK != rc)
{
fprintf(stderr, "SQL error: %s\\n", zErrMsg);
}
else
{
fprintf(stdout, "select table successfully\\n");
}
sqlite3_close(db);
return 0;
}
请看输出:
7. 更新并查询
#include<stdio.h>
#include<sqlite3.h>
static int callback(void *NotUsed, int argc, char **argv, char **azColName)
{
int i = 0;
for(i = 0; i < argc; i++)
{
printf("%s = %s\\n",azColName[i], argv[i]?argv[i]:"NULL");
}
printf("\\n");
return 0;
}
int main()
{
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);
return -1;
}
else
{
fprintf(stderr,"open database succeddfully\\n");
}
sql = "update company set ADDRESS = 'RUS' where ID = 3;\\
select * from company;";
rc = sqlite3_exec(db, sql, callback, 0, &zErrMsg);
if(SQLITE_OK != rc)
{
fprintf(stderr, "SQL error: %s\\n", zErrMsg);
}
else
{
fprintf(stdout, "update table successfully\\n");
}
sqlite3_close(db);
return 0;
}
8. 删除并查询
#include<stdio.h>
#include<sqlite3.h>
static int callback(void *NotUsed, int argc, char **argv, char **azColName)
{
int i = 0;
for(i = 0; i < argc; i++)
{
printf("%s = %s\\n",azColName[i], argv[i]?argv[i]:"NULL");
}
printf("\\n");
return 0;
}
int main()
{
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);
return -1;
}
else
{
fprintf(stderr,"open database succeddfully\\n");
}
sql = "delete from company where ID = 2;\\
select * from company;";
rc = sqlite3_exec(db, sql, callback, 0, &zErrMsg);
if(SQLITE_OK != rc)
{
fprintf(stderr, "SQL error: %s\\n", zErrMsg);
}
else
{
fprintf(stdout, "delete table successfully\\n");
}
sqlite3_close(db);
return 0;
}
以上是关于Linux下利用c/c++使用sqlite的主要内容,如果未能解决你的问题,请参考以下文章