您的位置:首页 > 数据库

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

2015-08-25 17:16 183 查看
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。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: