SQLITE3 在C/C++ 中的应用

1 篇文章 0 订阅
1 篇文章 0 订阅

1.准备SQLite源文件

首先去SQLite官网去下载源文件:官网网站
如果在WIN下编程,需要先用下载的源文件生成静态库文件。具体方法如下:

  1. 解压下载的sqlite-amalgamation-3180000.zip,得到的“sqlite3.h”、“sqlite3.c”、“sqlite3ext.h”三个文件添加到VS空项目中。
  2. 编译项目,生成sqlite3.dll,sqlite3.obj文件。
  3. 将sqlite3.obj文件复制到VS文件夹中lib.exe所在目录下,用管理员权限打开cmd,输入命令:lib sqlite3.obj,生成静态库sqlite3.lib。
  4. 将sqlite3.lib和sqlite3.h添加到需要编译的VS项目中就可以使用SQLite了。

在Linux下使用不用执行这一步,具体使用方法后面会提到。

2.SQLite Interface

在C/C++中使用SQLite最重要的三个接口就是sqlite3_open、sqlite3_exec和sqlite3_close,有了这三个接口就能简单的使用数据库了。
sqlite3_open用于打开并连接到SQLite数据库,并返回一个连接对象。
sqlite3_exec用于执行SQL语句,运行时,需要配套一个SQL语句和一个回调函数,执行时,数据库会把SQL语句进行解析,然后编译,最后去执行。
sqlite3_close用于断开与SQL数据库的连接,如果仍有未完成的查询,sqlite3_close将返回SQLITE_BUSY,并显示错误消息。
如果遇到需要重复或者循环执行SQL语句的情况,选择使用sqlite3_exec函数会反复执行解析和编译过程,效率会非常低。
遇到这种情况时,推荐大家使用sqlite3_stmt这个数据结构。sqlite3_stmt的使用方法如下:

  1. 利用sqlite3_prepare_v2()创建stmt对象。
  2. 调用sqlite_bind将应用程序的数据存储到原始SQL的参数中。
  3. 调用一次或者多次sqlite3_step去执行语句。
  4. 如果需要执行多次sqlite3_step,需要使用sqlite3_reset()去重置stmt对象, 然后执行步骤2,重新赋值。
  5. 整个操作完成后,调用sqlite3_finalize()去销毁并释放stmt对象

上面提到的接口在SQL官网中有详细的介绍,这里不具体展开说明,想了解的朋友可以自己查一下,链接在这SQLite Interface。在重复执行SQL语句的时候,相比sqlite3_exec,利用stmt对象,只需要用sqlite3_prepare_v2函数对SQL语句执行一次解析、编译,sqlite3_step执行多次,这样减少了解析和编译的次数,效率会提高很多。

3.实例

前面提到了在WINDOW下使用SQLite的方法,在LINUX下就不需要那么多繁琐的步骤了,在生成目标文件的时候,记得加上sqlite3.c源文件就可以了,详见3.4 CMakeLists.txt。下面附上代码。

3.1 create database

//createtable.c
#include <stdio.h>
#include <stdlib.h>
#include <sqlite3.h> 

static int callback(void *NotUsed, int argc, char **argv, char **azColName){
   int i;
   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;
   
   /* Open database */
   rc = sqlite3_open("test.db", &db);
   if( rc ){
      fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
      return(0);
   }else{
      fprintf(stdout, "Opened database successfully\n");
   }
   
   /* Create SQL statement */
   sql = "CREATE TABLE SCHOOL("  \
         "NUM INT PRIMARY KEY     NOT NULL," \
         "NAME           TEXT    NOT NULL," \
         "AGE            INT     NOT NULL," \
         "SEX        CHAR(50));" ;
         
   /* Execute SQL statement */
   rc = sqlite3_exec(db, sql, callback, 0, &zErrMsg);
   if( rc != SQLITE_OK ){
   fprintf(stderr, "SQL error: %s\n", zErrMsg);
      sqlite3_free(zErrMsg);
   }else{
      fprintf(stdout, "Table created successfully\n");
   }
   sqlite3_close(db);
   return 0;
}

3.2 insert value

//insert.c
#include <sqlite3.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>

typedef enum {
    index_key = 1,
    index_name,
    index_age,
    index_sex,
}INDEX_EN;

typedef struct{
    char name[10];
    int age;
    char sex[10];
}INPUTDATA_ST;

id insertData(int key, void *data);
sqlite3* sqldb1 = NULL;

void main(void)
{  
    int mInputCount = 0;
    char *zErrMSG = NULL;
    int len = 0;
    
    int res = sqlite3_open("test.db", &sqldb1);
    if( !res ){
      fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(sqldb1));
    }else{
      fprintf(stdout, "Opened database successfully\n");
    }
    
    INPUTDATA_ST inputdata;
    memset(&inputdata, 0 ,sizeof(INPUTDATA_ST));
    strcpy(inputdata.name, "TONG");
    inputdata.age = 19;
    strcpy(inputdata.sex, "male");
    
    char data[50];
    memset(data, 0 ,sizeof(data));
    memcpy(data, &inputdata, sizeof(inputdata));  
    insertData(1, data);
}

void insertData(int key, void *data)
{
    const char* sql = NULL;
    sql = "INSERT INTO SCHOOL (NUM,NAME,AGE,SEX) VALUES(?,?,?,?);";
    sqlite3_stmt* stmt = NULL;
    const char *pzTail = NULL;
    
    INPUTDATA_ST *inputdata = (INPUTDATA_ST *)data;
    sqlite3_prepare_v2(sqldb1, sql, -1, &stmt, &pzTail);
    sqlite3_bind_int(stmt, index_key, key);
    sqlite3_bind_text(stmt, index_name, inputdata->name, strlen(inputdata->name), SQLITE_STATIC);
    sqlite3_bind_int(stmt, index_age, inputdata->age);
    sqlite3_bind_text(stmt, index_sex, inputdata->sex, strlen(inputdata->sex), SQLITE_STATIC);
    
    int res = sqlite3_step(stmt);
    if(res == SQLITE_DONE){
        printf("Insert success.\n");
    }else{
        printf("Insert failed. Errorcode = %d.\n",res);
    }
    
    sqlite3_reset(stmt);
    sqlite3_finalize(stmt);
}

3.3 Select value


#include <stdio.h>
#include <stdlib.h>
#include <sqlite3.h> 

static int callback(void *NotUsed, int argc, char **argv, char **azColName){
   int i;
   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;
   
   /* Open database */
   rc = sqlite3_open("test.db", &db);
   if( rc ){
      fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
      return(0);
   }else{
      fprintf(stderr, "Opened database successfully\n");
   }
   
   /* Create SQL statement */
   sql = "SELECT * FROM  SCHOOL ";  
   /* Execute SQL statement */
   rc = sqlite3_exec(db, sql, callback, 0, &zErrMsg);
   
   if( rc != SQLITE_OK ){
      fprintf(stderr, "SQL error: %s\n", zErrMsg);
      sqlite3_free(zErrMsg);
   }else{
      fprintf(stdout, "Records created successfully\n");
   }
   
   sqlite3_close(db);
   return 0;
}

3.4 CMakeLists.txt

CMAKE_MINIMUM_REQUIRED(VERSION 2.8.10)
ADD_EXECUTABLE(create ${PROJECT_SOURCE_DIR}/src/createtable.c sqlite3.c)
ADD_EXECUTABLE(insert ${PROJECT_SOURCE_DIR}/src/insert.c sqlite3.c)
ADD_EXECUTABLE(select ${PROJECT_SOURCE_DIR}/src/select.c sqlite3.c)
INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/include)
TARGET_LINK_LIBRARIES(create pthread dl)
TARGET_LINK_LIBRARIES(insert pthread dl)
TARGET_LINK_LIBRARIES(select pthread dl)

最后附上运行结果:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值