c/c++两种方式操作sqlite
使用exec
sqlite3_open(const char *filename, sqlite3 **ppDb)
打开一个指向 SQLite 数据库文件的连接,返回一个用于其他 SQLite 程序的数据库连接对象。
如果 filename 参数是 NULL 或 ':memory:',那么 sqlite3_open() 将会在 RAM 中创建一个内存数据库,这只会在 session 的有效时间内持续。
如果文件名 filename 不为 NULL,那么 sqlite3_open() 将使用这个参数值尝试打开数据库文件。如果该名称的文件不存在,sqlite3_open() 将创建一个新的命名为该名称的数据库文件并打开。
sqlite3_exec(sqlite3*, const char *sql, sqlite_callback, void *data, char **errmsg)
提供了一个执行 SQL 命令的快捷方式,SQL 命令由 sql 参数提供,可以由多个 SQL 命令组成。
第一个参数 sqlite3 是打开的数据库对象,sqlite_callback 是一个回调,data 作为其第一个参数,errmsg 将被返回用来获取程序生成的任何错误。
sqlite3_exec() 程序解析并执行由 sql 参数所给的每个命令,直到字符串结束或者遇到错误为止。
sqlite3_close(sqlite3*)
关闭之前调用 sqlite3_open() 打开的数据库连接。所有与连接相关的语句都应在连接关闭之前完成。如果还有查询没有完成,sqlite3_close() 将返回 SQLITE_BUSY 禁止关闭的错误消息。
例:
#include <stdio.h>
#include <stdlib.h>
#include <sqlite3.h>
//如果回调在 sqlite_exec() 程序中作为第三个参数,那么
//SQLite 将为 SQL 参数内执行的每个 SELECT 语句中处理的每个记录调用这个回调函数
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 = %sn", 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";
/* 打开数据库 */
rc = sqlite3_open("test.db", &db);
if( rc ){
fprintf(stderr, "Can't open database: %sn", sqlite3_errmsg(db));
exit(0);
}else{
fprintf(stderr, "Opened database successfullyn");
}
/* 创建sql语句*/
sql = "SELECT * from COMPANY";
/* 执行sql语句 */
rc = sqlite3_exec(db, sql, callback, (void*)data, &zErrMsg);
if( rc != SQLITE_OK ){
fprintf(stderr, "SQL error: %sn", zErrMsg);
sqlite3_free(zErrMsg);
}else{
fprintf(stdout, "Operation done successfullyn");
}
//关闭数据库
sqlite3_close(db);
return 0;
}
使用sqlite3_stmt
1.打开数据库
//
参数1filename:指定的sqlites数据库文件;对于sqlite3_open()和sqlite3_open_v2() ,filename参数被解释成UTF-8; 对于sqlite3_open16(),则被解释成UTF-16;
参数2:数据库句柄通过*ppDb返回,即使发生了一些错误;
若sqlite无法分配内存来保存sqlite3对象,*ppDb将被写入NULL,而不是指向sqlite3对象的指针;
返回值:成功打开(创建)数据库,返回SQLITE_OK;否则返回错误代码;可用sqlite3_errmsg()或sqlite3_errmsg16()获取失败后的错误英文描述;
SQLITE_API int sqlite3_open(
const char *filename, /* Database filename (UTF-8) */
sqlite3 **ppDb /* OUT: SQLite db handle */
);
SQLITE_API int sqlite3_open16(
const void *filename, /* Database filename (UTF-16) */
sqlite3 **ppDb /* OUT: SQLite db handle */
);
SQLITE_API 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_v2()接口工作原理类似sqlite3_open(),只是它接收两个附加参数;用于对新的数据库连接进行附加控制;sqlite3_open_v2()的flags参数必须至少包含以下三个标志组合之一;
#define SQLITE_OPEN_READONLY 0x00000001 /* Ok for sqlite3_open_v2() */读
#define SQLITE_OPEN_READWRITE 0x00000002 /* Ok for sqlite3_open_v2() */写
#define SQLITE_OPEN_CREATE 0x00000004 /* Ok for sqlite3_open_v2() */没有则创建
除了上述必须的标志,还支持以下可选标志:
#define SQLITE_OPEN_URI 0x00000040 /* 可以将文件名解释为URL */
#define SQLITE_OPEN_MEMORY 0x00000080 /* 数据库将作为内存中的数据库打开 */
#define SQLITE_OPEN_NOMUTEX 0x00008000 /* 允许不同的线程同时使用SQLite,只要每个线程使用不同的数据块连接 */
#define SQLITE_OPEN_FULLMUTEX 0x00010000 /* 多个线程可在同一时间安全的使用同一个数据库连接(互斥锁将阻塞任何实际并发,但在这种模式下,尝试一下没有坏处)*/
#define SQLITE_OPEN_SHAREDCACHE 0x00020000 /* 启用共享缓存*/
#define SQLITE_OPEN_PRIVATECACHE 0x00040000 /* 数据库被打开并禁用共享缓存*/
sqlite3_open_v2()第四个参数是sqlite3_vfs对象的名称;若为NULL,则使用默认的sqlite3 vfs对象;
2.绑定语句和stmt,并执行
// 准备语句
int sqlite3_prepare_v2(
sqlite3 *db, /* db 表示数据库连接句柄; */
const char *zSql, /* zSql 表示将要被编译的语句;, UTF-8 encoded */
int nByte, /* nByte 表示 zSql 的长度,如果为-1则表示读取直到字符串结束; */
sqlite3_stmt **ppStmt, /* stmt对象 */
const char **pzTail /* 如果 pzTail 不为NULL,由于sqlite3_prepare_v2 只会编译 zSql 中的第1条语句,则pzTail 会被用来指向 zSql 中剩余未被编译的语句的首字节;pzTail 一般 传NULL; */
);
//绑定参数
int sqlite3_bind_int64(sqlite3_stmt *,int,sqlite3_int64);
(stmt对象,第几个参数,传入参数内容)
int sqlite3_bind_text(sqlite3_stmt *,int,const char(*),int,void(*)(void*));
(stmt对象,第几个参数,传入参数内容,字符串对象,字符串大小,null)
// 执行
int sqlite3_step(sqlite3_stmt*);
//函数功能:执行 sqlite3_prepare_v2 产生的准备语句pStmt,sqlite3_step会被执行一次或多次以 求 //pStmt 的值;
//函数说明:sqlite3_step 的行为取决语句于pStmt如何产生,假如是使用老版本的接口sqlite3_prepare()
//和sqlite3_prepare16(),返回值会是 SQLITE_BUSY, SQLITE_DONE, SQLITE_ROW, SQLITE_ERROR或 //SQLITE_MISUSE,而v2版本的接口sqlite3_prepare_v2()和sqlite3_prepare16_v2()则会同时返回这些结
//果码和扩展结果码。
// 完成
int sqlite3_finalize(sqlite3_stmt *pStmt);
//函数功能:删除准备语句pStmt;可以在pStmt的任何生命周期使用;注意,不要使用任何已经被finalize 的
//准备语句pStmt
参数传出:ppStmt 用来指向编译过的准备语句,可以直接被 sqlite3_step 执行;如果发生错误则ppStmt 为NULL;注意,调用程序需要负责删除 ppStmt ,可以通过调用 sqlite3_finalize 实现;
函数返回:打开成功则返回SQLITE_OK;否则返回错误码,通过sqlite3_errmsg可以获取到错误信息;
SQLITE_BUSY : 数据库引擎无法获取执行任务所需要的数据库锁。如果错误码发生在事务之外,可以尝试再次执行语句;如果错误发生在事务之内,必须回滚事务;
SQLITE_DONE : 语句已经成功完成执行,sqlite3_step不能再被调用,除非调用sqlite3_reset重置回初始状态;
SQLITE_ROW : 如果正在执行的准备语句pStmt返回了任何数据,在每次新的行数据准备好之后,SQLITE_ROW会被返回。返回的任何数据可以通过 sqlite3_column_xxxx系列函数获取;再次调用sqlite3_step可以继续获取新的行数据;
SQLITE_ERROR : 发生运行时错误,可通过sqlite3_errmsg获取错误信息;sqlite3_step不能再被调用;
SQLITE_MISUSE : 表示sqlite3_step被非法使用,可能准备语句pStmt在之前已经被finalized,也可能pStmt在前面已经发生错误或已经成功完成执行;或者是多个线程同时使用了该数据库连接;
例:
#define text_db "./test.db"
#define mode SQLITE_OPEN_FULLMUTEX|SQLITE_OPEN_READRITE|SQLITE_OPEN_CREATE
sqlite3* t_db;
const char* sql="select * form table1 where k1>? and k2=?";
sqlite3_stmt stmt=null;
int a1=0;
const char*a2;
int rc = 0;
rc=sqlite3_open_v2(text_db,&t_db,mode,NULL)
if(rc!=SQLITE_OK){
return -1}
sqlite3_prepare_v2(t_db,sql,-1,&stmt,NULL);
sqlite3_bind_int64(stmt,1,num_1);
sqlite3_bind_text(stmt,2,text_2);
while(sqlite3_step(stmt)==SQLITE_ROW){
a1=sqlite_column_int(stmt,0)
char*a2=sqlite_column_text(stmt,1)
}
sqlite3_finalize(stmt);
sqlite3_close_v2(t_db);