C/C++调用sqlite3接口详解
https://blog.csdn.net/fangye945a/article/details/86484547
2019年01月15日 00:04:50 fangye945a 阅读数:450
sqlite3的C/C++接口用法可分为两种:回调形式与非回调形式。所谓回调形式其实就是通过回调的方式处理sql语句执行结果,非回调形式就是待sql语句执行完毕后再通过返回值和相关函数来判断、获取执行结果。
一、sqlite3非回调形式接口用法
1、sqlite3_open 打开sqlite3数据库的连接
在sqlite3数据库管理系统中,用结构体sqlite3来表示一个打开的数据库对象(sqlite3数据库连接对象),函数原型及用法如下:
-
int sqlite3_open(const char *filename, sqlite3 **ppDb);
-
filename:要打开的sqlite3数据库的路径名
-
ppDb: 二级指针,用来保存打开的数据库的连接对象。
-
返回值: 成功返回SQLITE_OK,失败返回其他值。
2、 sqlite3_close: 关闭数据库连接对象
int sqlite3_close(sqlite3*);
3、SQL语句对象
sqlite3_stmt 这个结构体用来描述一个SQL语句对象。我们的应用都是通过SQL语句对象去发送sql指令给数据库管理系统的。
4、sqlite3_prepare_v2: 编译SQL语句,并创建一个SQL语句对象
-
int sqlite3_prepare_v2(
-
sqlite3 *db, // 数据库连接对象
-
const char *zSql, // 指向原始sql语句(要编译的sql语句),可以包含变量名的
-
int nByte, // < 0: 编译zSql到第一个\0为止
-
// >0: 编译zSql中前面nByte个字符
-
// =0: 什么也不编译
-
sqlite3_stmt **ppStmt, // *ppStmt用来保存编译好的sql语句对象
-
const char **pzTail // *pzTail如果不为空,则*pzTail指向zSql中编译的第一条完整sql语句后面的第一个字符。
-
);
-
返回值:成功返回SQLITE_OK,失败返回其他值.
zSql指向原始的SQL语句:
(1) 不包括参数名
"CREATE TABLE SCORE (\
NUM INTEGER PRIMARY KEY, \
NAME VARCHAR(255) NOT NULL,\
SCORE INTEGER\
);"
char *sql = "INSERT INTO STU VALUES(2, 'HULONGTENG', 53) ;";
(2)包括参数名
parameters:
编译的SQL语句中可以包含"变量/参数",其值可以在运行期间通过特定的参数接口来指定。
char *sql = "INSERT INTO STU VALUES(变量, 变量, 变量) ;";
有如下几种方式指定变量名:
:AAAA 命名参数,参数名为AAAA
@AAAA 命名参数,参数名为@AAAA
$AAAA 命令参数,参数名为$AAAA, 参数名可以包含一个或多个:: 和().
例子:
char *sql = "INSERT INTO STU VALUES(@NUM, @NAME, @SCORE) ;";
4、给参数赋值
(1) 获取参数索引。因为所有的绑定参数的函数,都是通过参数索引去指定参数的。
sqlite3_bind_parameter_index用来获取zName在SQL语句对象sqlite3_stmt中的索引。
函数原型:
-
int sqlite3_bind_parameter_index(sqlite3_stmt*, const char *zName);
-
返回值:成功返回索引值(>0),假如没有匹配的参数名找到,则返回0
(2) 给参数赋值: 绑定值到变量/参数
参数: SQL语句对象,参数索引,要设置的参数值
-
int sqlite3_bind_double(sqlite3_stmt*, int , double);
-
int sqlite3_bind_int(sqlite3_stmt *, int , int);
-
int sqlite3_bind_int64(sqlite3_stmt *, int , sqlite3_int64);
参数: SQL语句对象,参数索引
int sqlite3_bind_null(sqlite3_stmt* , int);
参数: SQL语句对象,参数索引,要设置的字符串指针,字符串的长度,函数指针用来释放字符串(可以为空)
int sqlite3_bind_text(sqlite3_stmt *, int, const char *, int , void (*) (void *));
5、sqlite3_step: 用来执行编译好的SQL语句对象(由sqlite3_stmt指定),每次返回一行执行结果。
函数原型及用法:
-
int sqlite3_step(sqlite3_stmt*);
-
sqlite3_stmt:指向编译好的要执行的SQL语句对象
-
返回值: SQLITE_BUSY: 没获取到锁,语句没执行。
-
SQLITE_DONE: sql语句执行完成。
-
SQLITE_ERROR: 出错啦
-
SQLITE_MISUSE: 使用方法不当
-
SQLITE_ROW: 假如SQL语句执行有返回结果,SQLITE_ROW返回。然后调用者调用sqlite3_column解析结果。
6、查询结果分析函数
若sql语句为SELECT语句,它的返回结果是一个结果表,则需要用额外的函数接口去获取这些结果表中的记录。
若调用sqlite3_step函数则需要判断返回值,并对执行结果表一行一行的处理,直到返回值为SQLITE_DONE为止。
-
int sqlite3_column_count(sqlite3_stmt *pStmt); //返回结果行中有多少列
-
int sqlite3_column_type(sqlite3_stmt *pStmt, int iCol); //返回结果行中第iCol列的数据类型
-
返回值: SQLITE_INTEGER :整数类型
-
SQLITE_FLOAT: 浮点类型
-
SQLITE_TEXT: 文本类型,char *
-
SQLITE_BLOB: blob
-
SQLITE_NULL: 空类型
判断出类型后,调用如下相应类型的接口获取结果集中当前行中第iCol列的值。
-
const void *sqlite3_column_blob(sqlite3_stmt*, int iCol);
-
int sqlite3_column_bytes(sqlite3_stmt*, int iCol);
-
int sqlite3_column_bytes16(sqlite3_stmt*, int iCol);
-
const char *sqlite3_column_decltype(sqlite3_stmt *, int iCol);
-
const void *sqlite3_column_decltype16(sqlite3_stmt *, int iCol);
-
double sqlite3_column_double(sqlite3_stmt*, int iCol);
-
int sqlite3_column_int(sqlite3_stmt*, int iCol);
-
long long int sqlite3_column_int64(sqlite3_stmt*, int iCol);
-
const char *sqlite3_column_name(sqlite3_stmt*, int iCol);
-
const void *sqlite3_column_name16(sqlite3_stmt*, int iCol);
-
const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol);
-
const void *sqlite3_column_text16(sqlite3_stmt*, int iCol);
也可以不通过sqlite3_step 函数来获取执行结果,使用sqlite3_get_table 函数直接获取整个结果表。
函数原型为:
-
int sqlite3_get_table(
-
sqlite3 *db, /* An open database */
-
const char *zSql, /* SQL to be evaluated */
-
char ***pazResult, /* Results of the query */
-
int *pnRow, /* Number of result rows written here */
-
int *pnColumn, /* Number of result columns written here */
-
char **pzErrmsg /* Error msg written here */
-
);
-
第1个参数为数据库连接对象。
-
第2个参数是sql 语句,跟sqlite3_exec 里的sql 是一样的。是一个很普通的以\0结尾的char*字符串。
-
第3个参数是查询结果(可理解为二维数组的地址)。
-
第4个参数是查询出多少条记录(即查出多少行,不包括字段名那行)。
-
第5个参数是多少个字段(多少列)。
-
第6个参数是错误信息
-
pazResult返回的字符串数量实际上是(*pnRow+1)*(*pnColumn),因为前(*pnColumn)个是字段名
使用sqlite3_get_table 函数后,需要使用对应的sqlite3_free_table函数来释放查询结果所申请的内存。函数原型:
void sqlite3_free_table(char **result); //释放掉查询结果申请的内存空间
6、sqlite3_reset:用来复位sql语句对象,以便下一轮的参数赋值
int sqlite3_reset(sqlite3_stmt *pStmt);
7、sqlite3_finalize:用来销毁一个SQL语句对象,与sqlite3_prepare_v2创建的SQL语句对象对应。
int sqlite3_finalize(sqlite3_stmt *pStmt);
使用示例一(sqlite3_step 方式获取执行结果):
-
#include <sqlite3.h>
-
#include <stdio.h>
-
#include <string.h>
-
#include <errno.h>
-
int main(int argc, char *argv[])
-
{
-
sqlite3 *pdb;
-
int r ;
-
/*step 1: 打开数据库连接对象*/
-
r = sqlite3_open(argv[1], &pdb );
-
if (r != SQLITE_OK)
-
{
-
perror("sqlite3_open error");
-
return -1;
-
}
-
/*step 2: sql语句对象。*/
-
sqlite3_stmt *pStmt;
-
char *sql= "SELECT STUINFO.SID,SNAME,CNAME,SCORE\
-
FROM STUINFO, COURCE, SCORE\
-
WHERE STUINFO.SID = SCORE.SID \
-
AND COURCE.CID = SCORE.CID ;";
-
r = sqlite3_prepare_v2(
-
pdb, //数据库连接对象
-
sql, //指向原始sql语句字符串
-
strlen(sql) , //
-
&pStmt,
-
NULL
-
);
-
if (r != SQLITE_OK)
-
{
-
perror("sqlite3_prepare_v2 error:");
-
return -1;
-
}
-
while (1)
-
{
-
static int first = 1;
-
int i;
-
/*2.2 执行SQL语句*/
-
r = sqlite3_step(pStmt);
-
if (r == SQLITE_DONE)
-
{
-
printf("o la\n");
-
break;//执行完成
-
}
-
else if (r == SQLITE_ROW) //获取到一行的结果
-
{
-
int cNum =0 ;//结果集中有多少列
-
cNum = sqlite3_column_count(pStmt);
-
if (first)
-
{
-
for (i = 0; i < cNum; i++)
-
{
-
//返回结果集中第i列的名字
-
const char *p = sqlite3_column_name(pStmt, i);
-
printf("%s\t", p);
-
}
-
printf("\n---------------------------\n");
-
first = 0;
-
}
-
int iType; //第i列的数据类型
-
for (i = 0; i < cNum; i++)
-
{
-
//获取结果集中第i列的数据类型
-
iType = sqlite3_column_type(pStmt, i);
-
if (iType == SQLITE_INTEGER)
-
{
-
int iValue;
-
//获取结果集中第i列的数据值
-
iValue = sqlite3_column_int(pStmt, i);
-
printf("%d\t", iValue);
-
}else if (iType == SQLITE_FLOAT)
-
{
-
double iValue;
-
//获取结果集中第i列的数据值
-
iValue = sqlite3_column_double(pStmt, i);
-
printf("%g\t", iValue);
-
}else if (iType == SQLITE_TEXT)
-
{
-
const char * iValue;
-
//获取结果集中第i列的数据值
-
iValue = sqlite3_column_text(pStmt, i);
-
printf("%s\t", iValue);
-
}
-
}
-
printf("\n");
-
}
-
}
-
//销毁一个SQL语句对象
-
sqlite3_finalize(pStmt);
-
/*step 3: 关闭数据库连接对象*/
-
sqlite3_close(pdb);
-
return 0;
-
}
使用示例二(sqlite3_get_table 方式获取执行结果):
-
#include <sqlite3.h>
-
#include <stdio.h>
-
#include <string.h>
-
#include <errno.h>
-
#define TABLE_NAME xxx //表名
-
#define CARD_ID xxx //卡ID
-
#define TYPE xxx //类型
-
int main(int argc, char *argv[])
-
{
-
sqlite3 *pdb;
-
int rc = 0; //返回值
-
int nrow = 0; //查询到数据的行数
-
int ncolumn = 0; //查询到数据的列数
-
char **azResult; //二维数组存放结果
-
char sql[128]={0}; //sql语句
-
char *zErrMsg = NULL; //错误信息
-
/*step 1: 打开数据库连接对象*/
-
rc = sqlite3_open(argv[1], &pdb );
-
if (r != SQLITE_OK)
-
{
-
perror("sqlite3_open error");
-
return -1;
-
}
-
/*step 2: sql语句对象。*/
-
sqlite3_stmt *pStmt;
-
sprintf(sql,"SELECT * FROM %s WHERE cardId = '%s' AND type = %d;", TABLE_NAME, CARD_ID, TYPE );
-
rc = sqlite3_prepare_v2(
-
pdb, //数据库连接对象
-
sql, //指向原始sql语句字符串
-
strlen(sql) , //
-
&pStmt,
-
NULL
-
);
-
if (rc != SQLITE_OK)
-
{
-
perror("sqlite3_prepare_v2 error:");
-
return -1;
-
}
-
printf("The SQL CMD:%s\n",sql);
-
rc = sqlite3_get_table( pdb, sql, &azResult, &nrow, &ncolumn, &zErrMsg ); //查询数据库
-
if( rc != SQLITE_OK )
-
{
-
fprintf(stderr,"Can't get table: %s",sqlite3_errmsg(pdb));
-
return -1;
-
}
-
printf( "nrow = %d ,ncolumn = %d\n", nrow, ncolumn ); //打印查询结果表的行数和列数
-
if( nrow !=0 && ncolumn != 0 ) //有查询结果,不包含表头所占行数
-
{
-
int i=0,j=0;
-
for(i=0; i<= nrow; i++) //打印查询结果
-
{
-
for(j=0; j<ncolumn; j++)
-
{
-
if(i==0) //第0行为数据表头
-
{
-
printf("%s\t", azResult[i+j]);
-
}
-
else
-
printf("%s\t", azResult[i+j]);
-
}
-
printf("\n");
-
}
-
}
-
sqlite3_free_table(azResult); //释放掉 azResult的内存空间
-
sqlite3_finalize(pStmt); //销毁一个SQL语句对象
-
/*step 3: 关闭数据库连接对象*/
-
sqlite3_close(pdb);
-
return 0;
-
}
二、sqlite3回调形式接口用法
一步到位的函数接口: sqlite3_exec
sqlite3_exec其实是sqlite3_prepare_v2、sqlite3_step、sqlite3_finalize 三个函数的组合。
函数原型及用法:
-
int sqlite3_exec( sqlite3* , //指向数据库连接对象
-
const char *sql , //指向要执行的SQL语句,一般不带参数。
-
int (*callback) (void *, int, char **, char **), //回调函数
-
void *arg, //这个函数将作为callback的第一个参数传入
-
char **errmsg //用来保存出错的信息
-
);
-
第一个参数,数据库连接对象
-
第二个参数,要执行的sql语句,可以执行多条语句以;分开
-
第三个参数,函数指针,回调函数。一般在sql语句为select语句时,需要回调。每查询到一条结果时(一行),就调用该回调函数。
-
int (*callback)(
-
void *, //sqlite3_exec的第四个参数
-
int, //结果中有多少列
-
char **, // char *column_values[],这一行每列的值(转化成字符串)
-
char ** //char *column_names[],这一行每列的名字(字符串)
-
),
-
回调函数的返回值: 返回0表示成功,其他值表示失败,回调函数执行失败了(返回非0值),sqlite3_exec就不执行下面的语句了。
-
第四个参数:将作为回调函数的第一个参数.
-
第五个参数: *errmsg将保存执行过程中的错误信息。
-
返回值: 成功返回0, 失败返回其他值。
使用示例:
-
#include <sqlite3.h>
-
#include <stdio.h>
-
#include <string.h>
-
#include <errno.h>
-
int select_cb(void *data, int cNum, char *column_values[], char *column_names[]) //回调函数,处理sql语句执行结果
-
{
-
int *p = (int *)data;
-
int i;
-
if ( *p )
-
{
-
for (i = 0; i < cNum; i++)
-
{
-
printf("%s\t", column_names[i]);
-
}
-
printf("\n");
-
*p = 0;
-
}
-
for (i = 0; i < cNum; i++)
-
{
-
printf("%s\t",column_values[i]);
-
}
-
printf("\n");
-
return 0;
-
}
-
int main(int argc, char *argv[])
-
{
-
sqlite3 *pdb;
-
int r ;
-
/*step 1: 打开数据库连接对象*/
-
r = sqlite3_open(argv[1], &pdb );
-
if (r != SQLITE_OK)
-
{
-
perror("sqlite3_open error");
-
return -1;
-
}
-
/* sql语句 */
-
char *sql= "SELECT STUINFO.SID,SNAME,CNAME,SCORE\
-
FROM STUINFO, COURCE, SCORE\
-
WHERE STUINFO.SID = SCORE.SID \
-
AND COURCE.CID = SCORE.CID ;";
-
int first = 1;
-
/*step 2: 执行sql语句*/
-
r = sqlite3_exec(pdb,sql,select_cb,(void*)&first,NULL);
-
/*step 3: 关闭数据库连接对象*/
-
sqlite3_close(pdb);
-
return 0;
-
}
回调形式接口详细可参考: http://www.runoob.com/sqlite/sqlite-c-cpp.html