Sqlite (七核心API

概述
     SQLite提供了一系列接口供用户访问数据库,主要包括连接数据库,处理SQL,迭代查询结果等。本文会针对我们使用SQLite的主要场景,列出核心的API,详细介绍API的用法并给出代码用例。
1.打开关闭数据库
sqlite3_open_v2
原型:

int sqlite3_open_v2(
const char *filename, /* Database filename (UTF-8) */
sqlite3 **ppDb, /* OUT: SQLite db handle */
int flags, /* Flags */
const char *zVfs /* Name of VFS module to use */
);

作用:打开一个数据库连接
关键的参数:flags
SQLITE_OPEN_NOMUTEX: 设置数据库连接运行在多线程模式(没有指定单线程模式的情况下)
SQLITE_OPEN_FULLMUTEX:设置数据库连接运行在串行模式。
SQLITE_OPEN_SHAREDCACHE:设置运行在共享缓存模式。
SQLITE_OPEN_PRIVATECACHE:设置运行在非共享缓存模式。
SQLITE_OPEN_READWRITE:指定数据库连接可以读写。
SQLITE_OPEN_CREATE:如果数据库不存在,则创建。

sqlite3_close_v2
原型:

int sqlite3_close_v2(sqlite3*);

作用:关闭数据库连接,若关闭时连接上有未提交的事务,该事务会自动回滚。

1.1 例子:打开关闭数据库连接

sqlite3* pDb;
char* filename="/u01/sqlite/test.db";
sqlite3_open_v2(filename, &pDb, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_NOMUTEX | SQLITE_OPEN_SHAREDCACHE, NULL);
....
....
sqlite3_close_v2(pDb);

打开数据库文件test.db,对应的数据库连接可读可写,以多线程模式运行,并且运行在共享缓存模式,执行完操作后,关闭数据库连接。

2.更新SQL
更新SQL主要包括创建表,插入,删除,更新记录等,SQLite中常用的更新API有两个,一个是sqlite3_exec,另外一个是sqlite3_prepare_v2。

2.1 sqlite3_exec
原型:

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

其中参数sql可以包含多个SQL命令,语句之间以分号隔开,sqlite3_exec()将解析和执行sql字符串中的每个命令,直到到达该字符串的末尾或遇到错误。对于运行修改数据库的命令(创建,插入,删除,更新)非常适合,一个函数调用就可以完成全部操作。需要注意的是,虽然sqlite3_exec()可以执行多个SQL命令,但是函数不保证事务,即已执行成功的语句,不会因为后面执行失败的语句而回滚。

2.2 sqlite3_perpare_v2
原型:

int sqlite3_prepare_v2(
sqlite3 *db, /* Database handle */
const char *zSql, /* SQL statement, UTF-8 encoded */
int nByte, /* Maximum length of zSql in bytes. */
sqlite3_stmt **ppStmt, /* OUT: Statement handle */
const char **pzTail /* OUT: Pointer to unused portion of zSql */
);

sqlite3_exec实际上是将编译,执行进行了封装,与之等价的一组函数是 sqlite3_prepare_v2(), sqlite3_step()和sqlite3_finalize()。sqlite3_prepare_v2()编译SQL语句生成VDBE执行码,sqlite3_step()执行,sqlite3_finalize()关闭语句句柄,释放资源。两种方式,都可以通过调用sqlite3_changes(pdb),得到语句影响的行数。

2.3两种方式比较
(1).sqlite3_exec方式接口使用很简单,实现同样的功能,比sqlite3_perpare_v2接口代码量少。
(2).sqlite3_prepare方式更高效,因为只需要编译一次,就可以重复执行N次。
(3).sqlite3_prepare方式支持参数化SQL。

鉴于两种方式的差异,对于简单的PRAGMA设置语句(PRAGMA cache_size=2000),事务设置语句(BEGIN TRANSACTION,COMMIT,ROLLBACK)使用sqlite3_exec方式,更简单;而对于批量的更新、查询语句,则使用sqlite3_prepare方式,更高效。

2.4 例子:prepare方式执行多sql的例子,pNext初始化在sql语句首部,执行完一个sql后,移动到下一个sql首部。

const char *pNext = (const char *)sql;
while (pNext && strlen(pNext) > 0) {
  rc = sqlite3_prepare_v2(pDb, pNext, -1, &pStmt, &pNext);
  if(SQLITE_OK != rc){
    错误处理
    break;
  }
   
    rc = sqlite3_step(pStmt);
    if(SQLITE_OK != rc && SQLITE_DONE != rc){
       错误处理
       break;
    }

    rc = SQLITE_OK;

    /*统计影响记录数目*/
    resultCount += sqlite3_changes(pDb);

    /* 清理语句句柄,准备执行下一个语句*/
    sqlite3_finalize(pStmt);
}

3.查询SQL
3.1 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 */
);

该函数接收SQL语句返回的所有记录,使用sqlite内部分配的内存,将其存储在参数resultp中,必须使用sqlite3_free_table()释放内存。由于结果集可能非常大,会导致内存撑爆,因此对于大结果集的查询,不建议采用这种方式。

3.2 sqlite3_prepare_v2
     prepare方式同样支持查询语句,主要分为3个阶段,编译,执行和结果集处理。前面更新SQL部分已经描述了prepare的基本步骤,这里主要讲结果集处理部分。首先通过sqlite3_column_count()可以得到结果集的列数目,通过sqlite3_column_type()可以得到具体某列的存储类型,方便我们调用合适的sqlite3_column_xxx接口处理字段值。主要有以下几类:
sqlite3_column_int
sqlite3_column_int64
sqlite3_column_double
sqlite3_column_text
sqlite3_column_blob

3.3 例子:遍历结果集

int rc = sqlite3_prepare_v2(pDb, sql, -1, &pStmt, NULL);
//获取列数目
int n_columns = sqlite3_column_count(pStmt);
do{
  ret = sqlite3_step(stmt);
  if (ret == SQLITE_ROW) 
  {
    //处理每一列
    for (i = 0; i < n_columns; i++)
    {
          /*获取列存储类型*/
      type = sqlite3_column_type(stmt,i);
      switch(type)
      {
        case SQLITE_INTEGER:
         /*处理整型*/
        sqlite3_column_int(stmt,i);
        break;
        case SQLITE_FLOAT:
        /*处理浮点数*/
        sqlite3_column_double(stmt,i);
        break;
        case SQLITE_TEXT:
        /*处理字符串*/
        sqlite3_column_text(stmt,i);
              break;
        case SQLITE_BLOB:
        /*处理二进制*/
        sqlite3_column_blob(stmt, i));
         break;
        case SQLITE_NULL:
        /*处理空*/
      }
    }
  }
  else if (ret == SQLITE_DONE) //结束
  { 
    break;
  }
}while(true);

4.参数绑定
     SQLite通过prepare接口可以支持参数化的SQL语句,即带问号的SQL语句。比如查询语句select * from t where id=?,或者插入语句 insert into t(a,b,c) values(?,?,?)。通过参数化SQL,可以实现一次编译多次执行的目的,由于问号是没有意义的,因此需要调用sqlite3_bind_xxx接口来绑定具体的参数。主要有以下几类:
sqlite3_bind_int
sqlite3_bind_int64
sqlite3_bind_double
sqlite3_bind_text
sqlite3_bind_blob
sqlite3_bind_null
关于绑定参数这里提一点,对于sqlite3_bind_text和sqlite3_bind_blob接口,绑定参数占据的存储空间是否可以被SQLite重用。接口中通过最后一个参数指定,参数值可以为SQLITE_STATIC和SQLITE_TRANSIENT。

SQLITE_STATIC:通知bind函数,参数使用空间是常量,不会改变,sqlite内部无需拷贝副本。
SQLITE_TRANSIENT:通知bind函数,参数使用空间可能会改变,sqlite内部需要有自己的副本。

4.1 例子:批量导入

//begin a transaction
if(sqlite3_exec(pdb, "begin", NULL, NULL, &errmsg) != SQLITE_OK)
{
  错误处理
  return ERROR;
}

sqlite3_prepare_v2(pdb, "insert into t1 values(?,?,?);", &stmt);
for (i = 0; i < n_rows; i++)
{
  for (j = 0; j < n_columns; j++)
  {
    switch(type)
    {
      case SQLITE_INTEGER:
      /*处理整型*/
      sqlite3_bind_int()
      break;
      case SQLITE_FLOAT:
      /*处理浮点型*/
      sqlite3_bind_double()
      break;
      case SQLITE_TEXT:
      /*处理字符串类型*/
      sqlite3_bind_text()
      break;
      case SQLITE_BLOB:
      /*处理二进制类型*/
      sqlite3_bind_blob
      break;
      case SQLITE_NULL:
      sqlite3_bind_null(stmt, index); 
      break;   
    }    
  }

  sqlite3_step(stmt);  //执行
  sqlite3_reset(stmt); //将已编译的SQL语句恢复到初始状态,保留语句相关的资源
}

sqlite3_finalize(stmt); //结束语句,释放语句句柄

if(sqlite3_exec(pdb, "commit", NULL, NULL, &errmsg) != SQLITE_OK)
{
  错误处理      return ERROR; 
}

小结
     本文详细描述了SQLite中实现创建,修改,查询数据库的接口使用,包括单SQL语句,多SQL语句和参数化SQL。主要从四个场景展开描述,打开关闭数据库连接,更新语句,查询语句和参数化语句,并且对于每一种使用场景,给出了相应的代码示范,希望能对大家熟悉使用SQLite有所帮助。

原文地址:https://blog.csdn.net/zhaofuguang/article/details/91882636

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


SQLite架构简单,又有Json计算能力,有时会承担Json文件/RESTful的计算功能,但SQLite不能直接解析Json文件/RESTful,需要用Java代码硬写,或借助第三方类库,最后再拼成insert语句插入数据表,代码非常繁琐,这里就不展示了。参考前面的代码可知,入库的过程比较麻烦,不能只用SQL,还要借助Java或命令行。SPL是现代的数据计算语言,属于简化的面向对象的语言风格,有对象的概念,可以用点号访问属性并进行多步骤计算,但没有继承重载这些内容,不算彻底的面向对象语言。...
使用Python操作内置数据库SQLite以及MySQL数据库。
破解微信数据库密码,用python导出微信聊天记录
(Unity)SQLite 是一个软件库,实现了自给自足的、无服务器的、零配置的、事务性的 SQL 数据库引擎。SQLite 是在世界上最广泛部署的 SQL 数据库引擎。SQLite 源代码不受版权限制。本教程将告诉您如何使用 SQLite 编程,并让你迅速上手。.................................
安卓开发,利用SQLite实现登陆注册功能
相比大多数数据库而言,具有等优势,广泛应用于、等领域。
有时候,一个项目只有一个数据库,比如只有SQLite,或者MySQL数据库,那么我们只需要使用一个固定的数据库即可。但是一个项目如果写好了,有多个用户使用,但是多个用户使用不同的数据库,这个时候,我们就需要把软件设计成可以连接多个数据库的模式,用什么数据库,就配置什么数据库即可。4.Users实体类,这个实体类要和数据库一样的,形成一一对应的关系。11.Sqlite数据库,需要在代码里面创建数据库,建立表,再建立数据。8.我们开启MySQL数据库,然后进行调试,看程序的结果。2.安装SqlSugar。
基于Android的背单词软件,功能强大完整。
SQLite,是一款轻型的数据库,是遵守ACID的关系型数据库管理系统。说白了就是使用起来轻便简单,
Android的简单购物车案例
SQLite,是一款轻型的数据库,是遵守ACID的关系型数据库管理系统,它包含在一个相对小的C库中。它是D.RichardHipp建立的公有领域项目。它的设计目标是嵌入式的,而且已经在很多嵌入式产品中使用了它,它占用资源非常的低,在嵌入式设备中,可能只需要几百K的内存就够了。它能够支持Windows/Linux/Unix等等主流的操作系统,同时能够跟很多程序语言相结合,比如 Tcl、C#、PHP、Java等,还有ODBC接口,同样比起Mysql、PostgreSQL这两款开源的世界著名数据库...
Qt设计较为美观好看的登录注册界面(包含SQLite数据库以及TCP通信的应用)
SQLite是用C语言开发的跨平台小型数据库,可嵌入其他开发语言,也可在单机执行。SPL是用Java开发的跨平台的数据计算语言,可嵌入Java,可在单机执行,可以数据计算服务的形式被远程调用。两者的代码都是解释执行的。...
新建库.openDATA_BASE;新建表createtableLIST_NAME(DATA);语法:NAME关键字...<用逗号分割>删除表droptableNAME;查看表.schema查看表信息新建数据insertintoLIST_NAMEvalues();语法:CLASS,PARAMETER...,CLASS是类别,PARAMETER是参数<用逗号分割新建的
importsqlite3classDemo01:def__init__(self):self.conn=sqlite3.connect("sql_demo_001.db")self.cursor1=self.conn.cursor()self.cursor1.execute("select*fromtable_001wherename=?andid=?",('ssss&#0
 在客户端配置文件<configuration>节点下,添加:<connectionStrings>      <add name="localdb" connectionString="Data Source=config/local.db;Version=3;UseUTF16Encoding=True;" providerName="System.Data.SQLite.SQLiteFactory"/&g
提到锁就不得不说到死锁的问题,而SQLite也可能出现死锁。下面举个例子:连接1:BEGIN(UNLOCKED)连接1:SELECT...(SHARED)连接1:INSERT...(RESERVED)连接2:BEGIN(UNLOCKED)连接2:SELECT...(SHARED)连接1:COMMIT(PENDING,尝试获取EXCLUSIVE锁,但还有SHARED锁未释放,返回SQLITE_BUSY)连接2:INSERT...
SQLite是一种嵌入式数据库,它的数据库就是一个文件。由于SQLite本身是C写的,而且体积很小,所以,经常被集成到各种应用程序中,甚至在iOS和Android的App中都可以集成。Python就内置了SQLite3,所以,在Python中使用SQLite,不需要安装任何东西,直接使用。在使用SQLite前,我们先要搞清楚几个概念:表
设计思想————首先要确定有几个页面、和每个页面的大致布局由于是入门,我也是学习了不是很长的时间,所以项目比较low。。。。第一个页面,也就是打开APP的首页面:今天这个博客,先实现添加功能!:首先对主界面进行布局:其中activity_main.xml的代码为<?xmlversion="1.0"encoding="