zoukankan      html  css  js  c++  java
  • SQLite的使用

    简介


    SQLite官网
    http://www.sqlite.org/

    SQLite简介

      SQLite是一款轻型的数据库,是遵守ACID(原子性、一致性、隔离性和持久性)的关系式数据库管理系统。SQLite实现了多数的SQL-92标准,包括事务、触发器和多数的复杂查询。
      SQLite的设计目标是嵌入式的,它占用的资源非常低,目前在很多嵌入式产品中都使用了SQLite。
      SQLite是跨平台的、可移植的,能够支持Windows/Linux/Unix等主流操作系统,同时SQLite能够和很多程序语言相结合,例如Tcl、C#、PHP和Java等。在C/C++程序中可以很方便的使用SQLite库,Python自2.5版本后也内置了SQLite模块,模块名为sqlite3。
      SQLite第一个Alpha版本诞生于2000年5月。目前SQLite最新的版本是 3.11 。

    SQLite的特性

    1. ACID事务
    2. 开放源代码
    3. 小巧、独立、简单易用,同时功能不落后于流行的数据库
    4. 整个数据库存储在一个文件中,不需要服务器支持
    5. 跨平台,支持Windows/Linux/Unix等主流操作系统
    6. 支持多种开发语言,C, C++,PHP, Perl, Java, C#,Python等
    7. 简洁易用的API接口

    SQLite 管理客户端

    安装


    (一)通过编译源码安装

    下载地址 https://www.sqlite.org/download.html

    下载文件 sqlite-autoconf-3110000.tar.gz

    // 解压
    tar zxvf sqlite-autoconf-3110000.tar.gz
    
    // 安装
    cd sqlite-autoconf-3110000
    ./configure --prefix=/usr/local
    make
    make install

    源码编译会生成这样几个等的文件:

    /usr/bin/sqlite3

    /usr/local/include/sqlit3.h

    /usr/local/lib/libsqlite3.so

    image

    (二)通过包安装SQLite

    sudo apt-get install sqlite3 libsqlite3-dev

    编译程序的时候需要这样

    gcc dbtest.c -o dbtest –lsqlite3

    注:-l和sqlite3之间可以有空格。

    (三)不安装SQLite编译程序
    在Linux系统上,将dbtest.c程序保存在libsqlite3.so , sqlite3和sqlite3.h同一个目录下。
    可以通过执行这条命令编译文件:

    gcc dbtest.c -o dbtest -lsqlite3 -L.

    image

    sqlite3二进制程序和sqlite3.h都可以在SQLite官网下载到,libsqlite3.so的获取有两种方法:

    1)通过源码编译会在/usr/local/lib/目录下生成libsqlite3.so文件,cp出来就可以了;

    2)在系统/usr/lib/x86_64-linux-gnu目录下本来就有(我是64位的系统)。

    image

    如果安装了libsqlite3-dev,该目录下会多出如下的文件:

    image

    小测试


    下面就是dbtest.c的程序,只有打开和关闭的操作。

    #include <stdio.h>
    #include <stdlib.h>
    #include <sqlite3.h>
    
    int main(void)
    {
        sqlite3 *db = NULL;
        int rc;
        // 打开数据库,不存在会创建一个新的
        rc = sqlite3_open("my.db",&db);
        if(rc)  // 不为0,打开失败
        {
            fprintf(stderr,"Can't open database:%s
    ",sqlite3_errmsg(db));
            sqlite3_close(db);
            exit(0);
        }
        else
        {
            printf("open db success!
    ");
            sqlite3_close(db);
        }
        return 0;
    }

    编译时常见的错误

    1)没有找到头文件,错误信息包含下面这句:

    sqlite3.h: 没有那个文件或目录

    2)没有找到库文件,错误信息包含下面这些句子:

    : undefined reference to `sqlite3_open'
    : undefined reference to `sqlite3_errmsg'
    : undefined reference to `sqlite3_close'
    : undefined reference to `sqlite3_close'

    gcc的-l、-L、-I参数

    -l参数就是用来指定程序要链接的库,例如本程序中要链接libsqlite3.so,去掉前后缀就是了。

    放在/lib和/usr/lib和/usr/local/lib里的库直接用-l参数就能链接了。

    如果库文件不在这3个目录下,譬如说自己写的库,就需要用-L+Dir的方式指定库文件的目录。

    -include、-I参数是用来指定头文件目录,gcc默认目录是/usr/include

    SQLite API 函数


    SQLite是一个调用级别上的接口库,它能够嵌入到应用程序中。所有的API函数都是以sqlite3_前缀命名,并且在sqlite3.h中声明。

    序号API & 描述
    1 sqlite3_open(const char *filename, sqlite3 **ppDb)

    如果 filename 参数是 NULL 或 ':memory:',那么 sqlite3_open() 将会在 RAM 中创建一个内存数据库,这只会在 session 的有效时间内持续。

    如果文件不存在,SQLite将自动的创建数据库文件。

    2 sqlite3_exec(sqlite3*, const char *sql, sqlite_callback, void *data, char **errmsg)

    第一个参数 sqlite3 是打开的数据库对象,sqlite_callback 是一个回调,data 作为其第一个参数,errmsg 将被返回用来获取程序生成的任何错误。

    sqlite3_exec() 程序解析并执行由 sql 参数所给的每个命令,直到字符串结束或者遇到错误为止。

    3 sqlite3_close(sqlite3*)

    关闭数据库连接,并且释放了分配给该连接的所有资源。

    如果还有查询没有完成,sqlite3_close() 将返回 SQLITE_BUSY 禁止关闭的错误消息。

    注:在打开或创建一个数据库文件时,SQLite遵守一个懒惰策略:知道该文件被阅读访问时才真正的打开或者创建。

    sql字符串可以由多个SQL语句组成,例如:

    sql = "UPDATE COMPANY set SALARY = 25000.00 where ID=1; " 
             "SELECT * from COMPANY";

    sqlite3_exec()函数如果不需要回调,最简洁可以这样写:

    rc = sqlite3_exec(db, sql, 0, 0, &errorMsg);
    if(errorMsg)
        printf("%s
    ", errorMsg);
    else
        printf("success!
    ");

    判断出错的部分也可以这样写:

    if( rc != SQLITE_OK )
    {
        fprintf(stderr, "SQL error: %s
    ", zErrMsg);
        sqlite3_free(zErrMsg);
    }
    else
    {
        fprintf(stdout, "success!
    ");
    }

    回调函数的原型

    typedef int (*sqlite3_callback)(
    void*,    /* Data provided in the 4th argument of sqlite3_exec() */
    int,      /* The number of columns in row */
    char**,   /* An array of strings representing fields in the row */
    char**    /* An array of strings representing column names */
    );

    第一个参数通过sqlite3_exec的第第四个参数传入的

    第二个参数是结果行的列数

    第三个参数是行中列数据的指针

    第四个参数是行中列名称的指针

    如果sqlite3_exec的第三个参数回调函数指针不为空,那么它会为每个来自执行的SQL语句的结果行调用。

    如果在执行sql语句中有错误发生,那么当前的语句的执行被停止,后续的语句也被跳过。

    下面就是一个回调函数的具体例子:

    static int callback(void *data, int argc, char **argv, char **ColName){
       int i;
       fprintf(stderr, "%s: ", (const char*)data);
       for(i=0; i<argc; i++){
          printf("%s = %s
    ", ColName[i], argv[i] ? argv[i] : "NULL");
       }
       printf("
    ");
       return 0;
    }


    sqlite3_get_table()函数

    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 */
    );
    // 不论数据库查询是否成功,都释放 char** 查询结果
    void sqlite3_free_table(char **result);

    第1个参数数据库对象。
    第2个参数是 sql 语句,以结尾的字符串。
    第3个参数是查询结果,它依然一维数组。它内存布局是:第一行是字段名称,后面是紧接着是每个字段的值。
    第4个参数是查询出多少条记录(多少行)。
    第5个参数是多少个字段(多少列)。
    第6个参数是错误信息。

    pazResult返回的字符串数量实际上是(*pnRow+1)*(*pnColumn)

    下面就是一个sqlite3_get_table()函数的具体例子:

    result = sqlite3_get_table( db, “select * from table1”, &dbResult, &nRow, &nColumn, &errmsg );
    if( SQLITE_OK == result )    // 查询成功
    {
        index = nColumn;
        // dbResult 第一行数据是字段名称,从 nColumn 索引开始才是真正的数据
        printf( “查到%d条记录
    ”, nRow );
    
        for(  i = 0; i < nRow ; i++ )
        {
             printf( “第 %d 条记录
    ”, i+1 );
             for( j = 0 ; j < nColumn; j++ )
             {
                  printf( “字段名:%s  >  字段值:%s
    ”,  dbResult[j], dbResult [index] );
                  ++index;
                  // dbResult 的字段值是连续的,从第0索引到第 nColumn - 1索引都是字段名称,
            // 从第 nColumn 索引开始,后面都是字段值
    } printf( “-------- ” ); } } // 释放查询结果 sqlite3_free_table( dbResult );

    还有一个例子:

    char query(sqlite3 *db, const char *sql) {
        printf("%s
    ", sql);
        char *select_str = "SELECT";
        char *errorMsg;
        char *str_str = strstr(sql, select_str);
        if(str_str) {
            printf("in it, %s
    ", str_str);
            int row = 0, column = 0, i = 0;
            char **result;
            sqlite3_get_table(db, sql, &result, &row, &column, &errorMsg);
            printf("row:%d, column:%d
    ", row, column);
            for(; i < column * (row + 1); i++) {
                printf("result[%d]=%s
    ", i, result[i]);
            }
        }else{
            sqlite3_exec(db, sql, 0, 0, &errorMsg);
        }
        if(errorMsg){
            printf("%s
    ", errorMsg);
        }else{
            printf("success!
    ");
        }
    }

    sqlite3.h中定义的助记符常量

    #define SQLITE_OK           0   /* Successful result */
    /* beginning-of-error-codes */
    #define SQLITE_ERROR        1   /* SQL error or missing database */
    #define SQLITE_INTERNAL     2   /* Internal logic error in SQLite */
    #define SQLITE_PERM         3   /* Access permission denied */
    #define SQLITE_ABORT        4   /* Callback routine requested an abort */
    #define SQLITE_BUSY         5   /* The database file is locked */
    #define SQLITE_LOCKED       6   /* A table in the database is locked */
    #define SQLITE_NOMEM        7   /* A malloc() failed */
    #define SQLITE_READONLY     8   /* Attempt to write a readonly database */
    #define SQLITE_INTERRUPT    9   /* Operation terminated by sqlite3_interrupt()*/
    #define SQLITE_IOERR       10   /* Some kind of disk I/O error occurred */
    #define SQLITE_CORRUPT     11   /* The database disk image is malformed */
    #define SQLITE_NOTFOUND    12   /* Unknown opcode in sqlite3_file_control() */
    #define SQLITE_FULL        13   /* Insertion failed because database is full */
    #define SQLITE_CANTOPEN    14   /* Unable to open the database file */
    #define SQLITE_PROTOCOL    15   /* Database lock protocol error */
    #define SQLITE_EMPTY       16   /* Database is empty */
    #define SQLITE_SCHEMA      17   /* The database schema changed */
    #define SQLITE_TOOBIG      18   /* String or BLOB exceeds size limit */
    #define SQLITE_CONSTRAINT  19   /* Abort due to constraint violation */
    #define SQLITE_MISMATCH    20   /* Data type mismatch */
    #define SQLITE_MISUSE      21   /* Library used incorrectly */
    #define SQLITE_NOLFS       22   /* Uses OS features not supported on host */
    #define SQLITE_AUTH        23   /* Authorization denied */
    #define SQLITE_FORMAT      24   /* Auxiliary database format error */
    #define SQLITE_RANGE       25   /* 2nd parameter to sqlite3_bind out of range */
    #define SQLITE_NOTADB      26   /* File opened that is not a database file */
    #define SQLITE_NOTICE      27   /* Notifications from sqlite3_log() */
    #define SQLITE_WARNING     28   /* Warnings from sqlite3_log() */
    #define SQLITE_ROW         100  /* sqlite3_step() has another row ready */
    #define SQLITE_DONE        101  /* sqlite3_step() has finished executing */
    /* end-of-error-codes */

    其他


    SQLite 教程
    http://www.runoob.com/sqlite/sqlite-tutorial.html

    常用命令学习
    http://yuanzhifei89.iteye.com/blog/1123870
    http://blog.csdn.net/linchunhua/article/details/7184439

    [API]
    官方中的介绍:http://www.sqlite.org/cintro.html
    http://www.cnblogs.com/kfqcome/archive/2011/06/27/2136999.html
    http://blog.chinaunix.net/uid-8447633-id-3321394.html

    使用VC将sqlite3.def转化为sqlite3.lib
    http://www.letuknowit.com/topics/20120421/convert-sqlite-def-to-sqlite-lib.html/
    windows系统中使用C/C++操作sqlite数据库示例程序
    http://www.letuknowit.com/topics/20120422/use-c-or-cplusplus-connect-to-sqlite-in-windows.html/

  • 相关阅读:
    性能测试应用领域
    性能测试---不同视角看性能和相关术语
    Jmeter(二十五)Jmeter之系统函数
    Jmeter(二十四)Jmeter-Question之“加密请求参数”
    Web应用层协议---HTTP
    协议栈CheckList
    数据报表类(BI)项目测试应该如何去啃?
    #单元测试#以karma+mocha+chai 为测试框架的Vue webpack项目(二)
    解决未安装unit测试和jest的Vue项目运行karma start时的错误
    npm run dev运行Vue项目报错:Node Sass does not yet support your current environment
  • 原文地址:https://www.cnblogs.com/luoxu34/p/5235737.html
Copyright © 2011-2022 走看看