[Linux网络编程]sqlite3的介绍和使用+实例

Posted Windalove

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[Linux网络编程]sqlite3的介绍和使用+实例相关的知识,希望对你有一定的参考价值。

    在后置服务器需要对大量请求包数据进行甄别处理存储,所以常常需要对数据库操作。我们选择了sqlite3:SQLITE是一款非常小巧的嵌入式开源数据库软件,主要具备以下几点特点

  • 1 支援大多数的SQL指令
  • 2 一个档案就是一个数据库。不需要安装数据库服务器软件。
  • 3 sqlite 不需要任何数据库引擎
  • 4 完整的Unicode支援(因此没有跨语系的问题)。
  • 5 速度很快。
    更多可以参考博客
        文章只是简单进行记录,方便自己的查询使用,如有错误,欢迎指出。

1 注意点

  • 注意1: SQLITE_OK这个宏对应的是0
  • 注意2:sqlite3_open函数中,回调函数sqlite3_callback 和它后面的void*这两个位置都可以填NULL。填NULL表示你不需要回调。比如你做insert 操作,做delete操作,就没有必要使用回调。而当你做select 时,就要使用回调,因为sqlite3 把数据查出来,得通过回调告诉你查出了什么数据。
  • 注意3:sqlite3_get_table和sqlite3_free_table配合使用,及时释放空间
  • 注意4:sqlite3_get_table第3个参数是查询结果,它依然一维数组(不要以为是二维数组,更不要以为是三维数组)。它内存布局是:字段名称,后面是紧接着是每个字段的值。
  • 注意5:有open就要有close

2 函数原型

2.1 sqlite3_open

1. int sqlite3_open(
  const char *filename,   /* Database filename (UTF-8) */ 
  sqlite3 **ppDb          /* OUT: SQLite db handle */
);
功能: 比如:E:/test.db。文件名不需要一定存在,如果此文件不存在,sqlite会自动建立它。
参数1:	filename 数据库名
参数2:	ppDb 数据库操作句柄 (指针)
返回值:成功返回SQLITE_OK,失败返回错误码

2.2 sqlite3_close

2. int sqlite3_close(sqlite3* db);
功能: 关闭一个数据库
参数1:db操作数据库的指针(或者说句柄)
返回值:成功返回SQLITE_OK,失败返回错误码

2.3 sqlite3_errmsg

3. const char *sqlite3_errmsg(sqlite3* db);
功能:通过db句柄获得操作错误信息
返回值:返回错误信息首地址

2.4 sqlite3_exec

4. int sqlite3_exec(
  sqlite3* db,                                  /* An open database */
  const char *sql,                           /* SQL to be evaluated */
  int (*callback)(void*arg,int,char**,char**),  /* Callback function */
  void *arg,                                    /* 1st argument to callback */
  char **errmsg                              /* Error msg written here */
);

功能:这就是执行一条sql 语句的函数。
参数1:db 数据库操作句柄
参数2:sql 一条sqlite语句
参数3:callback回调函数(只有sql为查询语句的时候才执行 特别注意)
参数4:arg 给回调函数传参,如果不需要可以填入NULL
参数5:错误消息
返回值:成功返回SQLITE_OK,

int (*callback)(void*arg,int f_num,char** f_value,char** f_name),  /* Callback function */

功能:每找到一条记录 调用一次回调函数 将结果结果输出 (从上往下一条一条查询)
参数1:arg传递给回调函数的参数
参数2:f_num记录中包含的字段数目(表示为列)
参数3:f_value包含每个字段的指针数组(每列的值)
参数4:f_name包含每个字段的名称数组 (每列的名称)

2.5 sqlite3_get_table

5.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:db 数据表的句柄
参数2:zsql sql的语句  
参数3:result 指向sql语句执行结果的三级指针  此结果为申请内存存放的,它依然一维数组(不要以为是二维数组,更不要以为是三维数组)。它内存布局是:字段名称,后面是紧接着是每个字段的值。
参数4:nrow 满足条件记录的条数,几行
参数5:ncolumn 每条记录包含的字段数目,几列
参数6:errsg 指向错误信息的指针
成功返回:SQLITE_OK 失败返回错误码

2.6 sqlite3_free_table

6.void sqlite3_free_table(char **result);
功能:释放表的结果的内存
参数1:指向表结果的指针

3 报错宏解释

#define SQLITE_OK         0 /*成功结果*/
#define SQLITE_ERROR      1 /*SQL错误或缺少数据库*/
#define SQLITE_INTERNAL   2 /*SQLite中的内部逻辑错误*/
#define SQLITE_PERM       3 /*访问权限被拒绝*/
#define SQLITE_ABORT      4 /*回调例程请求中止*/
#define SQLITE_BUSY       5 /*数据库文件已锁定*/
#define SQLITE_LOCKED     6 /*数据库中的一个表被锁定*/
#define SQLITE_NOMEM      7 /*一个malloc()失败*/
#define SQLITE_READONLY   8 /*尝试写入只读数据库*/
#define SQLITE_INTERRUPT  9 /*由sqlite3_interrupt()终止的操作*/
#define SQLITE_IOERR      10 /*发生某种磁盘I/O错误*/
#define SQLITE_CORRUPT    11 /*数据库磁盘映像格式不正确*/
#define SQLITE_NOTFOUND   12 /*未知操作码sqlite3_interrupt()*/
#define SQLITE_FULL       13 /*插入失败,因为数据库已满*/
#define SQLITE_CANTOPEN   14 /*无法打开数据库文件*/
#define SQLITE_PROTOCOL   15 /*数据库锁协议错误*/
#define SQLITE_EMPTY      16 /*数据库为空*/
#define SQLITE_SCHEMA     17 /*数据库架构已更改*/
#define SQLITE_TOOBIG     18 /*字符串或BLOB超出大小限制*/
#define SQLITE_CONSTRAINT 19 /*由于约束冲突而中止*/
#define SQLITE_MISMATCH   20 /*数据类型不匹配*/
#define SQLITE_usage      21 /*库使用错误*/
#define SQLITE_NOLFS      22 /*使用主机不支持的操作系统功能*/
#define SQLITE_AUTH       23 /*授权被拒绝*/
#define SQLITE_FORMAT     24 /*辅助数据库格式错误*/
#define SQLITE_RANGE      25 /*第二个参数定义为sqlite3_bind超出范围*/
#define SQLITE_NOTADB     26 /*打开的不是数据库文件的文件*/
#define SQLITE_NOTICE     27 /*来自sqlite3_log()的通知*/
#define SQLITE_WARNING    28 /*来自sqlite3_log()的警告*/
#define SQLITE_ROW        100 /*sqlite3_step()已准备好另一行*/
#define SQLITE_DONE       101 /*sqlite3_step()已完成执行*/

4 apt-get指令 + 源码编译两种安装方式

sqlite3两种安装方式 apt-get指令 + 源码编译 [linux]

5 实例代码

参考博客

5.1 sqlite3_get_table函数使用实例

int main( int , char ** )
{
       sqlite3 * db;
       int result;
       char * errmsg = NULL;
char **dbResult; //是 char ** 类型,两个*号
       int nRow, nColumn;
       int i , j;
int index;
result = sqlite3_open( “c:\\\\Dcg_database.db”, &db );        
           if( result != SQLITE_OK )
             { //数据库打开失败
return -1;
}
//数据库操作代码
//假设前面已经创建了MyTable_1 表
//开始查询,传入的dbResult 已经是 char **,这里又加了一个 & 取地址符,传递进去的就成了 char ***
result = sqlite3_get_table( db, “select *from MyTable_1”,&dbResult, &nRow, &nColumn, &errmsg );
if( SQLITE_OK == result )
{ //查询成功
   index = nColumn; //前面说过 dbResult 前面第一行数据是字段名称,从 nColumn 索引开始才是真正的数据
    printf( “查到%d条记录\\n”, nRow );
    for(  i = 0; i < nRow ; i++ )
    {
        printf( “第 %d 条记录\\n”, i+1 );
        for( j = 0 ; j < nColumn; j++ )
        {
              printf( “字段名:%s  ?> 字段值:%s\\n”,  dbResult[j], dbResult [index] );
              ++index; // dbResult 的字段值是连续的,从第0索引到第 nColumn - 1索引都是字段名称,从第 nColumn 索引开始,后面都是字段值,它把一个二维的表(传统的行列表示法)用一个扁平的形式来表示
        }
        printf(-------\\n” );
    }
}
//到这里,不论数据库查询是否成功,都释放 char** 查询结果,使用 sqlite 提供的功能来释放
sqlite3_free_table( dbResult );
//关闭数据库
sqlite3_close( db );
return 0;
}

5.2 sqlite3_exec函数使用实例

//sqlite3的回调函数       
// sqlite 每查到一条记录,就调用一次这个回调
int LoadMyInfo( void * para,  intn_column,  char ** column_value,  char ** column_name )
{
//para是你在 sqlite3_exec 里传入的void * 参数
//通过para参数,你可以传入一些特殊的指针(比如类指针、结构指针),然后在这里面强制转换成对应的类型(这里面是void*类型,必须强制转换成你的类型才可用)。然后操作这些数据
//n_column是这一条记录有多少个字段 (即这条记录有多少列)
// char ** column_value 是个关键值,查出来的数据都保存在这里,它实际上是个1维数组(不要以为是2维数组),每一个元素都是一个 char * 值,是一个字段内容(用字符串来表示,以\\0结尾)
//char ** column_name 跟column_value是对应的,表示这个字段的字段名称
//这里,我不使用 para 参数。忽略它的存在.
int i;
printf( “记录包含 %d 个字段\\n”, n_column );
for( i = 0 ; i < n_column; i ++ )
{
    printf( “字段名:%s  ?> 字段值:%s\\n”,  column_name[i], column_value[i] );
}
printf(------------------\\n“ );       
return 0;
}
int main( int , char ** )
{
          sqlite3 * db;
          int result;
          char * errmsg =NULL;
          result =sqlite3_open( “c:\\\\Dcg_database.db”, &db );
                if( result !=SQLITE_OK )
                {
                //数据库打开失败
return -1;
}
//数据库操作代码
//创建一个测试表,表名叫MyTable_1,有2个字段: ID 和 name。其中ID是一个自动增加的类型,以后insert时可以不去指定这个字段,它会自己从0开始增加
result = sqlite3_exec( db, “create table MyTable_1( ID integerprimary key autoincrement, name nvarchar(32) ), NULL, NULL, errmsg );
if(result != SQLITE_OK )
{
     printf( “创建表失败,错误码:%d,错误原因:%s\\n”, result, errmsg );
}
//插入一些记录
result = sqlite3_exec( db, “insert into MyTable_1( name ) values ( ‘走路’ ), 0, 0, errmsg );
if(result != SQLITE_OK )
{
     printf( “插入记录失败,错误码:%d,错误原因:%s\\n”, result, errmsg );
}
result = sqlite3_exec( db, “insert into MyTable_1( name ) values ( ‘骑单车’ ), 0, 0, errmsg );
if(result != SQLITE_OK )
{
     printf( “插入记录失败,错误码:%d,错误原因:%s\\n”, result, errmsg );
}
result = sqlite3_exec( db, “insert into MyTable_1( name ) values ( ‘坐汽车’ ), 0, 0, errmsg );
if(result != SQLITE_OK )
{
     printf( “插入记录失败,错误码:%d,错误原因:%s\\n”, result, errmsg );
}
//开始查询数据库
result = sqlite3_exec( db, “select * from MyTable_1”, LoadMyInfo, NULL, errmsg );
//关闭数据库
sqlite3_close( db );
return 0;
}

如有错误,欢迎指出

以上是关于[Linux网络编程]sqlite3的介绍和使用+实例的主要内容,如果未能解决你的问题,请参考以下文章

SQLite3+Qt开发SQLite3简要介绍+在Qt5中的使用步骤

SQLite3使用笔记——插入

C语言 Linux网络编程(C/S架构) 在线词典

Ubuntu上面安装sqlite3可视化数据库软件

Linux 系统命令行下,对 SQLite3 数据库使用的一般操作

Linux下sqlite3常用命令!!!