sqlite的C/C++ API接口的基础操作与事务

版权声明:本文为博主原创文章,转载请注明出处。 https://blog.csdn.net/qq_30650153/article/details/82222425

1、C/C++ 接口 API

主要通过通过sqlite3_open,sqlite3_exec和qlite3_close来实现一个简单的数据库操作。

1.1、sqlite3_open

sqlite3_open(const char *filename, sqlite3 **ppDb)

  • 打开一个指向 SQLite 数据库文件的连接,返回一个用于其他 SQLite 程序的数据库连接对象
  • filename 参数是 NULL':memory:'sqlite3_open() 将会在 RAM 中创建一个内存数据库,这只会在 session 的有效时间内持续
  • filename不为NULLsqlite3_open()将使用这个参数值尝试打开数据库文件。如果该名称的文件不存在,sqlite3_open() 将创建一个新的命名为该名称的数据库文件并打开

1.2、sqlite3_exec

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

  • 提供了一个执行 SQL 命令的快捷方式,SQL 命令由 sql 参数提供,可以由多个 SQL 命令组成
  • 第一个参数sqlite3是打开的数据库对象,sqlite_callback是一个回调data作为其第一个参数errmsg将被返回用来获取程序生成的任何错误
  • sqlite3_exec()程序解析并执行由sql参数所给的每个命令,直到字符串结束或者遇到错误为止

1.3、sqlite3_close

sqlite3_close(sqlite3*)

  • 关闭之前调用 sqlite3_open() 打开的数据库连接。所有与连接相关的语句都应在连接关闭之前完成。如果还有查询没有完成,sqlite3_close() 将返回 SQLITE_BUSY 禁止关闭的错误消息

1.4、插入例程

void jobSerialInsertSQL(struct S_SERIAL_JOB serialjob)
{

    char* insertJob;
    char sql[255];
    sqlite3 *db;
    int rc;
    char *zErrMsg = 0;
    rc = sqlite3_open("jp.db",&db);
    if(rc)
    {
        printf("Can not open database:%s\n",sqlite3_errmsg(db));
        return;
    }

    insertJob = "INSERT INTO rt_jobserial (task_serial,task_id,point_tag,device_tag) VALUES (";
    sprintf(sql,"%s%d%s%d%s%d%s%d%s",
                insertJob,
                serialjob.task_serial,
                ",",
                serialjob.task_id,
                ",",
                serialjob.point_tag,
                ",",
                serialjob.device_tag,
                ")");
    rc = sqlite3_exec(db,sql,sqliteCallback,0,&zErrMsg);
    if( rc != SQLITE_OK)
    {
        printf("SQL ERROR: %s\n",zErrMsg);
        sqlite3_free(zErrMsg);
    }
    else{}
    sqlite3_close(db);

}

经过测试,上面代码在for循环运行插入1500条数据大约耗时1~2分钟,效率很低,在工程中是无法满足需求的。

默认SQLite的数据库插入操作,如果没有采用事务的话,它每次写入提交,就会触发一次事务操作,而这样几千条的数据,就会触发几千个事务的操作,这就是时间耗费的根源。

2、事务实现

2.1、什么是事务?

事务是用户定义的一些列数据操作,这些操作是一个完整的不可分的工作单元。一个事务要么全部执行,要么全部不执行。

2.2、事务属性(ACID)

原子性(Atomicity): 确保工作单位内的所有操作都成功完成,否则,事务会在出现故障时终止,之前的操作也会回滚到以前的状态。
一致性(Consistency):确保数据库在成功提交的事务上正确地改变状态。
隔离性(solation): 使事务操作相互独立和透明。
持久性(Durability): 确保已提交事务的结果或效果在系统发生故障的情况下仍然存在。

2.3、事务控制 

事务控制命令只与 DML 命令 INSERTUPDATEDELETE一起使用。他们不能在创建表或删除表时使用,因为这些操作在数据库中是自动提交的。

  • BEGIN TRANSACTION:开始事务处理。
  • COMMIT:保存更改,或者可以使用 END TRANSACTION 命令。
  • ROLLBACK:回滚所做的更改。

2.4、事务例程

void jobSerialInsertSQL(struct S_SERIAL_JOB *serialjob,int totalNum)
{
    char* insertJob;
    char sql[255];
    sqlite3 *db;
    int rc;
    char *zErrMsg = 0;
    int i = 0;
    bool isExecSuccess = true;
    rc = sqlite3_open("jp.db",&db);
    if(rc)
    {
        printf("Can not open database:%s\n",sqlite3_errmsg(db));
        return;
    }
    sqlite3_exec(db, "begin;", 0, 0, &zErrMsg); //开启事务
    insertJob = "INSERT INTO rt_jobserial (task_serial,task_id,point_tag,device_tag) VALUES (";
    for(i=0;i<totalNum;i++)
    {
            sprintf(sql,"%s%d%s%d%s%d%s%d%s",
                insertJob,
                serialjob[i].task_serial,
                ",",
                serialjob[i].task_id,
                ",",
                serialjob[i].point_tag,
                ",",    
                serialjob[i].device_tag,
                ")");
            rc = sqlite3_exec(db,sql,sqliteCallback,0,&zErrMsg);
            memset(sql,0,255);
            if( rc != SQLITE_OK)
            {
                isExecSuccess = false;
                printf("SQL ERROR: %s\n",zErrMsg);
                sqlite3_free(zErrMsg);
            }
            else{}
    }
    if(isExecSuccess)
    {
        sqlite3_exec(db, "commit;", 0, 0, 0); 
    }
    else
    {
        sqlite3_exec(db, "rollback;", 0, 0, 0); 
    }
    sqlite3_close(db);
}

经过测试,上面代码所需时间约为 70~90 ms。

猜你喜欢

转载自blog.csdn.net/qq_30650153/article/details/82222425
今日推荐