1、打开数据库
/*
** Open a new database handle.
*/
int sqlite3_open(const char *zFilename, sqlite3 **ppDb);
参数:
zFilename - 数据库文件名,不存在则创建
ppDb - 数据库句柄
代码示例:
sqlite3 *sdb = NULL;
if (sqlite3_open("test.db", &sdb))
{
fprintf(stderr, "sqlite3_open error\n");
return -1;
}
2、执行sql语句
2.1、使用sqlite3_exec
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 */
void *pArg, /* First argument to xCallback() */
char **pzErrMsg /* Write error messages here */
)
参数:
db - 数据库句柄
zSql - sql语句
xCallback - 产生查询结果时所执行的回调函数,如果不需要可以传NULL,如插入删除等操作
pArg - 传入回调函数的第一个参数
pzErrMsg - 错误信息,在执行sql语句产生错误的时候如果使用了该参数,需要调用sqlite3_free()释放
xCallback的类型定义:
/*
** The type for a callback function.
** This is legacy and deprecated. It is included for historical
** compatibility and is not documented.
*/
typedef int (*sqlite3_callback)(void*,int,char**, char**);
其中,
参数1:为sqlite3_exec传入的第4个参数
参数2:表字段的个数
参数3:一条字段值列表
参数4:字段名称列表
当使用sqlite3_exec查询表时,每查到一条记录就会调用一次回调函数。
代码示例:
//回调函数
int sqlite_callback(void *arg, int f_num, char **f_value, char **f_name)
{
printLog(LOGINFO, "filed num=[%d]", f_num);
for (int i = 0; i < f_num; i++)
{
printf("%10s | %s\n", f_name[i], f_value[i]);
}
return 0; //注意回调函数必须有返回值,且0为成功,否则会造成query aborted错误
}
//使用回调函数查询语句
int sql_exec_callback(sqlite3 *sdb)
{
char *errmsg = NULL;
char sql[256];
memset(sql, 0, sizeof(sql));
strcpy(sql, "SELECT * from students");
if (sqlite3_exec(sdb, sql, sqlite_callback, NULL, &errmsg))
{
fprintf(stderr,"sqlite3_exec error : [%s]\n", errmsg);
sqlite3_free(errmsg);
return -1;
}
return 0;
}
//不使用回调函数直接执行语句,如CREATE DELETE INSERT
int sql_exec(sqlite3 *db)
{
char sql[256];
memset(sql, 0, sizeof(sql));
strcpy(sql, "CREATE TABLE students (num int,name text,age int)");
if (sqlite3_exec(sdb, sql, NULL, NULL, NULL))
{
//sqlite3_errmsg()返回最近一次执行sql语句的错误
fprintf(stderr,"sqlite3_exec error : [%s]\n", sqlite3_errmsg(sdb));
return -1;
}
return 0;
}
2.2、使用sqlite3_get_table查询
int sqlite3_get_table(
sqlite3 *db, /* The database on which the SQL executes */
const char *zSql, /* The SQL to be executed */
char ***pazResult, /* Write the result table here */
int *pnRow, /* Write the number of rows in the result here */
int *pnColumn, /* Write the number of columns of result here */
char **pzErrMsg /* Write error messages here */
)
参数:
db - 数据库句柄
zSql - sql语句
pazResult - 保存查询语句查到的所有记录结果
pnRow - 行 代表查询到的记录条数
pnColumn - 列 代表的字段数
pzErrMsg - 错误信息,在执行sql语句产生错误的时候如果使用了该参数,需要调用sqlite3_free()释放
pazResult参数说明:
dbResult是字符串数组,假如数据库有4个字段,则dbResult[0]-[3]是字段名
dbResult[4]-[7]为第1条数据
dbResult[8]-[11]为第2条数据,以此类推…
dbResult的元素个数为 (nRow+1)*nColumn
且查询结束后要使用sqlite3_free_table()释放内存
代码示例:
char **dbResult = NULL;
int nRow = 0; //行 代表查询的记录条数
int nColumn = 0; //列 代表的字段数
int rc = sqlite3_get_table(sdb, sql, &dbResult, &nRow, &nColumn, &errmsg);
if (rc == SQLITE_OK)
{
printf("[%d]条数据 [%d]个字段\n", nRow, nColumn);
for (int i = 0; i < nColumn; i++)
{
/* 字段名 */
printf("%10s|", dbResult[i]);
}
printf("\n");
for (int i = nColumn; i < (nRow + 1) * nColumn; i++)
{
/* 值 */
printf("%10s|", dbResult[i]);
if ((i + 1) % nColumn == 0)
{
printf("\n");
}
}
}
sqlite3_free_table(dbResult);
2.3、使用sqlite3_step执行语句
需要使用的接口:
/*
sql语句准备
db - 数据库句柄
zSql - 准备的sql语句
nBytes - sql语句的长度
ppStmt - sqlite3_stmt结构指针
pzTail - 表示从zSql截取未使用的一部分
*/
int sqlite3_prepare_v2(
sqlite3 *db, /* Database handle. */
const char *zSql, /* UTF-8 encoded SQL statement. */
int nBytes, /* Length of zSql in bytes. */
sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */
const char **pzTail /* OUT: End of parsed string */
);
/*
用于查询使用,返回该条记录第iCol列的值,根据字段不同类型使用不同的接口
iCol - 表中最左侧,从0开始的索引值
*/
int sqlite3_column_int(sqlite3_stmt*, int iCol);
double sqlite3_column_double(sqlite3_stmt*, int iCol);
const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol);
/*
如下函数用绑定变量到准备好的sql语句中
如"INSERT into students values(?,?,?)" 第几个?代表第几个参数
或"INSERT into students values(:1,:2,:3)" :1:2:3分别代表参数序号1,2,3
如下接口:
参数1: sqlite3_stmt结构指针
参数2: sql语句参数索引号,从1开始
参数3: 传入sql语句中的参数
参数4: 有第四个参数的接口是指参数3的长度
参数5: 是用于BLOB和字符串绑定后的析构函数,用于在sqlite处理完blob或字符串之后处理它,一般为NULL
*/
int sqlite3_bind_int(sqlite3_stmt*, int, int);
int sqlite3_bind_doubule(sqlite3_stmt*, int, double);
int sqlite3_bind_text(sqlite3_stmt*, int, const char*, int, void(*)(void*));
代码示例:
//使用sqlite3_column_xxx()接口查询语句
int sql_query(sqlite3 *sdb)
{
sqlite3_stmt *stmt = NULL;
char sql[256];
memset(sql, 0, sizeof(sql));
strcpy(sql, "SELECT * from students");
if (sqlite3_prepare_v2(sdb, sql, strlen(sql), &stmt, NULL))
{
fprintf(stderr,"sqlite3_prepare_v2 error\n");
return -1;
}
while (sqlite3_step(stmt) == SQLITE_ROW) // SQLITE_ROW-100 结束标志为 SQLITE_DONE 101
{
int nCol = 0;
//假如字段名按顺序依次为num int,name text,age int
int num = sqlite3_column_int(stmt, nCol++);
char *name = sqlite3_column_text(stmt, nCol++);
int age = sqlite3_column_int(stmt, nCol++);
printf("%d|%s|%d\n", num, name, age);
}
sqlite3_finalize(stmt);
return 0;
}
//使用sqlite3_bind_xxx接口插入数据库
int sql_inster(sqlite3 *sdb)
{
sqlite3_stmt *pstmt = NULL;
char sql[256];
memset(sql, 0, sizeof(sql));
strcpy(sql, "INSERT into students values(:1,:2,:3)");
//strcpy(sql, "INSERT into students values(?,?,?)");//都可以
if (sqlite3_prepare_v2(sdb, sql, strlen(sql), &pstmt, NULL))
{
fprintf(stderr,"sqlite3_prepare_v2 error\n");
return -1;
}
for (int i = 0; i < 10; i++)
{
/* 插入10条 */
int nParm = 1;
int num = 1;
char *name = "zhangshan";
int age = 18;
sqlite3_bind_int(pstmt, nParm++, num);
sqlite3_bind_text(pstmt, nParm++, name, strlen(name), NULL);
sqlite3_bind_int(pstmt, nParm++, age);
if (SQLITE_DONE != sqlite3_step(pstmt))
{
printf("sqlite3_step error message :%s", sqlite3_errmsg(sdb));
}
sqlite3_reset(pstmt); //需要重置后再次调用sqlite3_step()
}
sqlite3_finalize(pstmt);
}
3、关闭数据库
最后用完需要关闭数据库释放资源。
int sqlite3_close(sqlite3 *db);
OVER