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);