Sqlite学习笔记(11)-API(2)

前端之家收集整理的这篇文章主要介绍了Sqlite学习笔记(11)-API(2)前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

2.2.3 执行Prepared Query
前面提到,预处理查询(Prepared Query)是sqlite执行所有sql命令的方式,包括以下三个过程:
(1)Preparation
分析器(parser),分词器(tokenizer)和代码生成器(code generator)把sql Statement编译成VDBE字节码,编译器会创建一个statement句柄(sqlite3_stmt),它包括字节码以及其它执行命令和遍历结果集的所有资源。
相应的C API为sqlite3_prepare_v2(),位于prepare.c文件中,如下:

int sqlite3_prepare_v2(
  sqlite3 *db,/* Database handle. */
  const char *zsql,/* UTF-8 encoded sql statement. */
  int nBytes,/* Length of zsql in bytes. */
  sqlite3_stmt **ppStmt,/* OUT: A pointer to the prepared statement */
  const char **pzTail       /* OUT: End of parsed string */
){
  int rc;
  rc = sqlite3LockAndPrepare(db,zsql,nBytes,1,0,ppStmt,pzTail);
  assert( rc==sqlITE_OK || ppStmt==0 || *ppStmt==0 );  /* VERIFY: F13021 */
  return rc;
}

(2) Execution
VDBE执行字节码,执行过程是一个步进(stepwise)的过程,每一步(step)由sqlite3_step()启动,并由VDBE执行一段字节码。在遍历结果集的过程中,它返回sqlITE_ROW,当到达结果末尾时,返回sqlITE_DONE。
相应的C API为sqlite3_step(),位于Vdbeapi.c文件中,如下:

int sqlite3_step(sqlite3_stmt *pStmt){
  int rc = sqlITE_OK;      /* Result from sqlite3Step() */
  int rc2 = sqlITE_OK;     /* Result from sqlite3Reprepare() */
  Vdbe *v = (Vdbe*)pStmt;  /* the prepared statement */
  int cnt = 0;             /* Counter to prevent infinite loop of reprepares */
  sqlite3 *db;             /* The database connection */

  if( vdbeSafetyNotNull(v) ){
    return sqlITE_MISUSE_BKPT;
  }
  db = v->db;
  sqlite3_mutex_enter(db->mutex);
  v->doingRerun = 0;
  while( (rc = sqlite3Step(v))==sqlITE_SCHEMA
         && cnt++ < sqlITE_MAX_SCHEMA_RETRY ){
    int savedPc = v->pc;
    rc2 = rc = sqlite3Reprepare(v);
    if( rc!=sqlITE_OK) break;
    sqlite3_reset(pStmt);
    if( savedPc>=0 ) v->doingRerun = 1;
    assert( v->expired==0 );
  }
  if( rc2!=sqlITE_OK ){
    const char *zErr = (const char *)sqlite3_value_text(db->pErr); 
    sqlite3DbFree(db,v->zErrMsg);
    if( !db->mallocFailed ){
      v->zErrMsg = sqlite3DbStrDup(db,zErr);
      v->rc = rc2;
    } else {
      v->zErrMsg = 0;
      v->rc = rc = sqlITE_NOMEM;
    }
  }
  rc = sqlite3ApiExit(db,rc);
  sqlite3_mutex_leave(db->mutex);
  return rc;
}

(3)Finalization
VDBE关闭statement,释放资源。
相应的C API为sqlite3_finalize(),位于Vdbeapi.c文件中,如下:

int sqlite3_finalize(sqlite3_stmt *pStmt){
  int rc;
  if( pStmt==0 ){ 
    rc = sqlITE_OK;
  }else{
    Vdbe *v = (Vdbe*)pStmt;
    sqlite3 *db = v->db;
    if( vdbeSafety(v) ) return sqlITE_MISUSE_BKPT;
    sqlite3_mutex_enter(db->mutex);
    checkProfileCallback(db,v);
    rc = sqlite3VdbeFinalize(v);
    rc = sqlite3ApiExit(db,rc);
    sqlite3LeaveMutexAndCloseZombie(db);
  }
  return rc;
}

这三步-preparation,execution,finalization-分别代表不同的statement句柄状态- prepared,active,or finalized。图2.3显示了这些步骤和状态。
下边我们可以用一段伪代码展示一下执行过程,代码如下:

# 1. Open the database,create a connection object (db) db = open('foods.db') # 2.A. Prepare a statement stmt = db.prepare('select * from episodes') # 2.B. Execute. Call step() is until cursor reaches end of result set. while stmt.step() == sqlITE_ROW print stmt.column('name') end # 2.C. Finalize. Release read lock. stmt.finalize() # 3. Insert a record stmt = db.prepare('INSERT INTO foods VALUES (…)') stmt.step() stmt.finalize() # 4. Close database connection. db.close()

图2.3 语句执行过程 2.2.4 执行Wrapped Query 前边已经提到过,wrapped query只是对prepared query的三个过程封装而已。Wrapped query包括二个函数sqlite3_exec()以及sqlite3_get_table()。这两个函数都可用于查询,不过sqlite3_exec()主要用于不返回数据的查询,而sqlite3_get_table()则相反。其中sqlite3_exec()位于Legacy.c,而sqlite3_get_table()位于table.c。

原文链接:https://www.f2er.com/sqlite/199394.html

猜你在找的Sqlite相关文章