SQLite 主要接口

SQLite打开数据库有3个接口:

SQLITE_API int sqlite3_open(
  const char *filename,   /* Database filename (UTF-8) */
  sqlite3 **ppDb          /* OUT: SQLite db handle */
);
SQLITE_API int sqlite3_open16(
  const void *filename,   /* Database filename (UTF-16) */
  sqlite3 **ppDb          /* OUT: SQLite db handle */
);
SQLITE_API 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 */
);

3个接口都可以用于创建打开数据库。返回值给ppDb参数,如果内存申请失败,则ppDb为NULL。

sqlite3_open是一个基本接口。使用UTF-8编码。

sqlite_open16主要区别是使用UTF-16编码。

sqlite_open_v2使用UTF-8编码,sqlite_open_v2加入了两个新参数。

注意:Windows用户必须用UTF-8


编译SQL语句

在执行SQL语句之前,首先要编译成字节码。就像是在做准备(prepare)。另外还有两个UTF-16的没有列出来

SQLITE_API int sqlite3_prepare(
  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 */
);
SQLITE_API 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 */
);

要计算好SQL语句的长度,注意单双字节。如果长度为空,则ppStmt为NULL。

返回值保存在ppStmt中做为下一步的参数。pzTail参数暂时没什么用。

两个接口的参数没有什么区别。在新程序中要使用v2,老的接口只是为了兼容。

注意:如果有并发操作会返回SQLITE_BUSY。

执行SQL语句

编译成功后,就可以执行了。只有一个接口。

SQLITE_API int sqlite3_step(sqlite3_stmt*);

入参是上一步得到的ppStmt。

返回值可能是

  • SQLITE_BUSY,被其他线程或进程锁住了。如果SQL语句是一个事务中的COMMIT,可以重试,如果不是事务中的COMMIT,则需要回滚。
  • SQLITE_DONE,执行完成。比如查询多行时已经到最后一行。
  • SQLITE_ROW,意思是还有新行。
  • SQLITE_ERROR,执行出错,只能是主键冲突,这时候就不要重试了。
  • SQLITE_MISUSE,非法调用,可能是因为此ppStmt已经被sqlite3_finalize()回收了。
注意:执行一次sqlite_step只能获取一行结果,直到返回SQLITE_DONE为止。

解析查询结果

SQLITE_API int sqlite3_column_count(sqlite3_stmt *pStmt);
SQLITE_API const char *sqlite3_column_name(sqlite3_stmt*, int N);
SQLITE_API const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol);

分别获取列的数目,获取列名,获取值。
注意:只有第一次sqlite_step才返回列名(因为列名存在第一行),其余的行都返回结果。

回收ppStmt

在执行完查询以后,需要回收ppStmt。以免内存泄漏。

SQLITE_API int sqlite3_finalize(sqlite3_stmt *pStmt);

一步到位的执行接口

SQLITE_API 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 */
);

sqlite3_exec封装了从sqlite3_prepare,sqlite3_step到sqlite3_finalize等步骤的接口。

如果callback参数不为空,则执行完成后调用此回调函数。但这就导致程序变成了异步。所以笔者只用了写入,而不用来查询。

sqlite3_exec可以一次性执行多个sql语句,但如果第一句出错,其余的都会跳过。

errmsg可以用于接收错误信息(如果有的话),用完一定要sqlite3_free()掉,否则会内存泄漏。

注意:正在执行此函数时一定不能关闭数据库连接。

关闭数据库连接

SQLITE_API int sqlite3_close(sqlite3*);
SQLITE_API int sqlite3_close_v2(sqlite3*);

注意:

如果ppStmt没有被finalize的话,执行sqlite3_close关闭数据库会报SQLITE_BUSY。

执行sqlite3_close_v2适合有垃圾回收的语言调用,因为析构函数的执行是随机的。

如果关闭后事务还正执行,则事务会回滚。


获取错误信息

应该妥善处理每次执行接口的返回值。

如果返回值不是SQLITE_OK或查询时的SQLITE_DONE,可以用sqlite_errmsg()获取详细的错误信息。



SQLite 主要接口,布布扣,bubuko.com

SQLite 主要接口

上一篇:表统计信息过旧导致执行慢的sql优化


下一篇:oracle sql_tunne ORACLE提供的sql优化