专栏首页Windows开发20分钟掌握sqlite库的使用

20分钟掌握sqlite库的使用

sqlite库是一个轻量级的数据库引擎,功能齐全,广泛应用于客户端产品(如Chrome浏览器)。

首先,从官网下载sqlite源码(sqlite3.c和sqlite3.h两个文件),添加到工程项目中。

然后,阅读sqlite库的API文档,下面3个API(sqlite3_open()、sqlite3_exec()、sqlite3_close())基本上就可以满足开发的需要。

/**
@name 打开数据库,获取数据库连接对象
@param filename 数据库文件完整路径,UTF8编码
@param ppDb 数据库连接对象,调用其它接口时需要传入
@return SQLITE_OK 成功,其它值是错误码
*/
int sqlite3_open(
    const char *filename,   /* Database filename (UTF-8) */
    sqlite3 **ppDb          /* OUT: SQLite db handle */
    );

/**
@name 执行SQL语句
@param pDb 数据库连接对象,sqlite3_open返回的值
@param sql 要执行的SQL语句,多个SQL语句之间使用分号(;)隔开
@param callback SQL执行过程中每个结果行都会进行回调,
                            SQL查询时必需设置回调获取查询结果
@param callback_context 作为callback的第一个参数,透传
@param errmsg 如果调用失败,返回错误内容,不需要时调sqlite3_free()释放
@return SQLITE_OK 成功,其它值是错误码
*/
int sqlite3_exec(
    sqlite3* pDb,                                  /* An open database */
    const char *sql,                           /* SQL to be evaluated */
    int(*callback)(void*, int, char**, char**),  /* Callback function */
    void * callback_context,                                    /* 1st argument to callback */
    char **errmsg                              /* Error msg written here */
    );

/**
int(*callback)(void* callback_context, int column_num, char** column_value, char** column_name);
回调有4个参数:
第一,callback_context 回调上下文,sqlite3_exec的callback_context,业务自己定义
第二,column_num 列数,column_value和column_name数组的大小
第三,column_value 各列的值
第四, column_name 各列的名字
如果返回值不是SQLITE_OK,sqlite3_exec将立即终止SQL执行,并返回失败
*/

/**
@name 关闭数据库连接对象
@param pDB 数据库连接对象, sqlite3_open返回的值
@return SQLITE_OK 成功,其它值是错误码
*/
int sqlite3_close(sqlite3* pDB);

sqlite库支持的主要数据类型有:NULL(空值)、INT(4位有符号整数)、INT8(8位有符号整数)、FLOAT、DOUBLE、TEXT(可变长度字符串,不限长度)、CHAR(n)(固定长度为n的字符串)、VARCHAR(n)(最大长度不超过n的字符串)。

下面示例参考tutorialspoint站点上的例子,说明如何使用sqlite库建表、增删改查。

COMPANY表包含5列:

第一, 员工ID,INT型,主键,不能为空

第二, 员工名字,TEXT型,不能为空

第三, 员工年龄,INT型,不能为空

第四, 员工地址,字符串50个字符

第五, 员工薪水,浮点数,可以有小数

#include <stdio.h>
#include <stdlib.h>
#include "sqlite/sqlite3.h" 

static int callback(void *NotUsed, int argc, char **azColValue, char **azColName) {
    int i;
    for (i = 0; i < argc; i++) {
        printf("%s = %s\n", azColName[i], azColValue[i] ? azColValue[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 Table */
    sql = "CREATE TABLE COMPANY("  \
        "ID INT PRIMARY KEY     NOT NULL," \
        "NAME           TEXT    NOT NULL," \
        "AGE            INT     NOT NULL," \
        "ADDRESS        CHAR(50)," \
        "SALARY         REAL );";

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

    /* Insert Table */
    sql = "INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY) "  \
        "VALUES (1, 'Paul', 32, 'California', 20000.00 ); " \
        "INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY) "  \
        "VALUES (2, 'Allen', 25, 'Texas', 15000.00 ); "     \
        "INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY)" \
        "VALUES (3, 'Teddy', 23, 'Norway', 20000.00 );" \
        "INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY)" \
        "VALUES (4, 'Mark', 25, 'Rich-Mond ', 65000.00 );";

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

    /* Select Table */
    sql = "SELECT * from COMPANY";

    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, "Operation done successfully\n");
    }

    /* Update Table */
    sql = "UPDATE COMPANY set SALARY = 25000.00 where ID=1; " \
        "SELECT * from COMPANY";

    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, "Operation done successfully\n");
    }

    /* Delete Table */
    sql = "DELETE from COMPANY where ID=2; " \
        "SELECT * from COMPANY";

    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, "Operation done successfully\n");
    }

    sqlite3_close(db);
    return 0;
}

本文分享自微信公众号 - Windows开发(gh_5216ec78fc5b),作者:kinglon

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-09-12

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 链接时无法解析符号checklist

    主要原因包括四类:函数声明与实现的原型不一致、函数声明与实现的作用域不同、函数声明但没有实现、使用DLL接口不当。

    gaigai
  • 支持定时任务的任务池

    任务池可以用来异步处理任务,比如清理过期日志、HTTP请求,本文介绍的任务池还支持定时触发任务,在SetTimer得注意的两个坑 一文中介绍了工作线程如果想使用...

    gaigai
  • 再谈程序自动退出定位技巧

    最近,笔者遇到一例程序自动退出,其原因不是程序自己退出,而是被外部其它程序结束了(特别是程序未签名很容易被安全软件给强杀),那么如何定位是哪个外部程序结束呢?

    gaigai
  • [pytorch] 图像识别之mixup/cutout/Margin loss....简单实现

    本人kaggle分享链接:https://www.kaggle.com/c/bengaliai-cv19/discussion/128592

    MachineLP
  • chip_seq质量评估之FRiP Score

    chip_seq是研究转录因子结合,组蛋白修饰的利器,这项技术虽然经过了很多年的发展,但是由于不同抗体的特异性,不同样本处理的复杂性,如何保证chip数据的高质...

    生信修炼手册
  • 图形数据库之Neo4j核心概念介绍(二)

    我是攻城师
  • P1004 方格取数

    题目描述 设有N*N的方格图(N<=9),我们将其中的某些方格中填入正整数,而其他的方格中则放 人数字0。如下图所示(见样例): A 0 0 0 0 ...

    attack
  • 如何利用curl命令访问Kubernetes API server

    kubectl 通过访问 Kubernetes API 来执行命令。我们也可以通过对应的TLS key, 使用curl 或是 golang client做同样的...

    我的小碗汤
  • 【HDU - 4340】Capturing a country(树形DP)

    n(<100)个城市组成的树。A攻击i城市需要a[i]代价,B需要b[i]。如果一个城市的邻居被A攻击了,那么A攻击它只要A[i]/2(整除)的代价,B同理。求...

    饶文津
  • JMeter 中实现发送Java请求

    如上图,填写Project Name,然后Next,打开以Java Settings界面

    授客

扫码关注云+社区

领取腾讯云代金券