SQLite剖析之编程接口详解

前言

  使用过程根据函数大致分为如下几个过程:

  • sqlite3_open()
  • sqlite3_prepare()
  • sqlite3_step()
  • sqlite3_column()
  • sqlite3_finalize()
  • sqlite3_close()

  这几个过程是概念上的说法,而不完全是程序运行的过程,如sqlite3_column()表示的是对查询获得一行里面的数据的列的各个操作统称,实际上在sqlite中并不存在这个函数。

1.sqlite3_open()

  该函数用来打开数据库。在操作数据库之前,首先要打开数据库。这个函数打开一个sqlite数据库文件的连接并且返回一个数据库连接对象。这个操作同时程序中的第一个调用的sqlite函数,同时也是其他sqlite api的先决条件。许多的sqlite接口函数都需要一个数据库连接对象的指针作为它们的第一个参数。

  函数定义:

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

  说明:

  假如这个要被打开的数据文件不存在,则一个同名的数据库文件将被创建。如果使用sqlite3_open和sqlite3_open_v2的话,数据库将采用UTF-8的编码方式,sqlite3_open16采用UTF-16的编码方式。

  返回值:

  如果sqlite数据库被成功打开(或创建),将会返回SQLITE_OK,否则将会返回错误码。Sqlite3_errmsg()或者sqlite3_errmsg16可以用于获得数据库打开错误码的英文描述,这两个函数定义为:

const char *sqlite3_errmsg(sqlite3*);
const void *sqlite3_errmsg16(sqlite3*);

  无论是否成功打开数据库, 都应该使用 sqlite3_close() 关闭数据库连接。

  参数说明:

  filename:需要被打开的数据库文件的文件名,在sqlite3_open和sqlite3_open_v2中这个参数采用UTF-8编码,而在sqlite3_open16中则采用UTF-16编码。

  ppDb:一个数据库连接句柄被返回到这个参数,即使发生错误。唯一的一场是如果sqlite不能分配内存来存放sqlite对象,ppDb将会被返回一个NULL值。

  flags:作为数据库连接的额外控制的参数,可以是SQLITE_OPEN_READONLY,SQLITE_OPEN_READWRITE和SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE中的一个,用于控制数据库的打开方式,可以和SQLITE_OPEN_NOMUTEXSQLITE_OPEN_FULLMUTEX, SQLITE_OPEN_SHAREDCACHE,以及SQLITE_OPEN_PRIVATECACHE结合使用,具体的详细情况可以查阅文档。

2.Sqlite3_prepare()

  这个函数将sql文本转换成一个准备语句(prepared statement)对象,同时返回这个对象的指针。这个接口需要一个数据库连接指针以及一个要准备的包含SQL语句的文本。它实际上并不执行(evaluate)这个SQL语句,它仅仅为执行准备这个sql语句。

  函数定义(仅列出UTF-8的)

int sqlite3_prepare(
  sqlite3 *db,            /* Database handle */  /* 成功打开的数据库句柄 */
  const char *zSql,       /* SQL statement, UTF-8 encoded */ /* UTF8编码的 SQL 语句 */
  int nByte,              /* Maximum length of zSql in bytes. */   /* 参数 sql 的字节数, 包含 ‘\0‘ */
  sqlite3_stmt **ppStmt,  /* OUT: Statement handle */ /* 输出:预编译语句句柄 */
  const char **pzTail     /* OUT: Pointer to unused portion of zSql */ /* 输出:指向 sql 语句中未使用的部分 */
);
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 */
);

  参数说明:

  db:数据指针。

  zSql:sql语句,使用UTF-8编码。

  nByte:如果nByte小于0,则函数取出zSql中从开始到第一个0终止符的内容;如果nByte不是负的,那么它就是这个函数能从zSql中读取的字节数的最大值。如果nBytes非负,zSql在第一次遇见’/000/或’u000’的时候终止.如果用户知道被传入的 sql 语句是以 ‘\0‘ 结尾的, 那么有一个更好的做法是:把nbytes的值设为该字符串的长度(包含‘\0‘), 这样可以避免 SQLite 复制该字符串的一份拷贝, 以提高程序的效率。

pzTail:上面提到zSql在遇见终止符或者是达到设定的nByte之后结束,假如zSql还有剩余的内容,那么这些剩余的内容被存放到pZTail中,不包括终止符。如果 pszTail 不为 NULL, 则 *pszTail 指向 sql 中第一个被传入的 SQL 语句的结尾. 该函数只编译 sql 的第一个语句, 所以 *pszTail 指向的内容则是未被编译的。

ppStmt:能够使用sqlite3_step()执行的编译好的准备语句的指针,如果错误发生,它被置为NULL,如假如输入的文本不包括sql语句。调用过程必须负责在编译好的sql语句完成使用后使用sqlite3_finalize()删除它。

  说明:

  如果执行成功,则返回SQLITE_OK,否则返回一个错误码。推荐在现在任何的程序中都使用sqlite3_prepare_v2这个函数,sqlite3_prepare只是用于前向兼容。

  备注:

  <1>准备语句(prepared statement)对象

typedef struct sqlite3_stmt sqlite3_stmt;        

  准备语句(prepared statement)对象一个代表一个简单SQL语句对象的实例,这个对象通常被称为“准备语句”或者“编译好的SQL语句”或者就直接称为“语句”。

语句对象的生命周期经历这样的过程:

    1. 使用sqlite3_prepare_v2或相关的函数创建这个对象
    2. 使用sqlite3_bind_*()给宿主参数(host parameters)绑定值
    3. 通过调用sqlite3_step一次或多次来执行这个sql
    4. 使用sqlite3——reset()重置这个语句,然后回到第2步,这个过程做0次或多次
    5. 使用sqlite3_finalize()销毁这个对象

  在sqlite中并没有定义sqlite3_stmt这个结构的具体内容,它只是一个抽象类型,在使用过程中一般以它的指针进行操作,而sqlite3_stmt类型的指针在实际上是一个指向Vdbe的结构体得指针。

  <2>宿主参数(host parameters)

  在传给sqlite3_prepare_v2()的sql的语句文本或者它的变量中,满足如下模板的文字将被替换成一个参数:

|  ?
|  ?NNN  //NNN代表数字
|  :VVV  //VVV代表字符
|  @VVV
|  $VVV

  在上面这些模板中,NNN代表一个数字,VVV代表一个字母数字标记符(例如:222表示名称为222的标记符),sql语句中的参数(变量)通过上面的几个模板来指定,如“select ? from ? “这个语句中指定了两个参数,sqlite语句中的第一个参数的索引值是1,这就知道这个语句中的两个参数的索引分别为1和2,使用”?”的话会被自动给予索引值,而使用”?NNN”则可以自己指定参数的索引值,它表示这个参数的索引值为NNN。”:VVV”表示一个名为”VVV”的参数,它也有一个索引值,被自动指定。

  例如:

INSERT INTO people (id, name) VALUES ( ?, ? );
INSERT INTO people (id, id2,name) VALUES ( ?1, ?1.?2 );  //作用:可以用同一个值绑定几个变量
INSERT INTO people (id, name) VALUES ( :id, :name );
INSERT INTO people (id, name) VALUES ( @id, @name );
INSERT INTO people (id, name) VALUES ( $id, $name );  //用来支持Tcl变量的扩展语法,除非使用Tcl编程,否则推荐使用“:<name>”版本

  可以使用sqlite3_bind_*()来给这些参数绑定值。

3.int sqlite3_bind_text(sqlite3_stmt*, int, const char*, int n,void(*)(void*))

  参数说明:

  第二个参数:为序号(从1开始)

  第三个参数:为字符串值

  第四个参数:为字符串长度

  第五个参数:为一个函数指针,SQLITE3执行完操作后回调此函数,通常用于释放字符串占用的内存。此参数有两个常数,SQLITE_STATIC告诉sqlite3_bind_text函数字符串为常量,可以放心使用;而SQLITE_TRANSIENT会使得sqlite3_bind_text函数对字符串做一份拷贝。一般使用这两个常量参数来调sqlite3_bind_text。statement准备好了以后,就是操作的执行了。

  sqlite3_bind_*系列函数还有好多: 

int sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*));  //功能:为查询结构体绑定数据

参数说明:

PARAM1(IN):查询结构体
PARAM2(IN):绑定第几个数据(sql语句中的第几个问号(?))
PARAM3(IN):二进制数据指针
PARAM4(IN):二进制数据长度
PARAM5(IN):析构回调函数,通常设置NULL,结束后自己释放

返回值:

SQLITE_OK 成功

说明:

绑定函数必须要在sqlite3_step前,sqlite3_prepare或者sqlite3_reset之后调用。

未绑定的参数缺省为NULL,类似的绑定函数还有以下:

int sqlite3_bind_double(sqlite3_stmt*, int, double);
int sqlite3_bind_int(sqlite3_stmt*, int, int);
int sqlite3_bind_int64(sqlite3_stmt*, int, sqlite_int64);
int sqlite3_bind_null(sqlite3_stmt*, int);
int sqlite3_bind_text(sqlite3_stmt*, int, const char*, int n, void(*)(void*));
int sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int, void(*)(void*));
int sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*); 

4.  sqlite3_step()

  这个过程用于执行有前面sqlite3_prepare创建的准备语句。这个语句执行到结果的第一行可用的位置。继续前进到结果的第二行的话,只需再次调用sqlite3_setp()。继续调用sqlite3_setp()知道这个语句完成,那些不返回结果的语句(如:INSERT,UPDATE,或DELETE),sqlite3_step()只执行一次就返回。

  函数定义:

int sqlite3_step(sqlite3_stmt*);

  返回值:

  函数的返回值基于创建sqlite3_stmt参数所使用的函数,假如是使用老版本的接口sqlite3_prepare()和sqlite3_prepare16(),返回值会是 SQLITE_BUSY, SQLITE_DONE, SQLITE_ROW, SQLITE_ERROR 或 SQLITE_MISUSE,而v2版本的接口sqlite3_prepare_v2()和sqlite3_prepare16_v2()则会同时返回这些结果码和扩展结果码。

  对所有V3.6.23.1以及其前面的所有版本,需要在sqlite3_step()之后调用sqlite3_reset(),在后续的sqlite3_ step之前。如果调用sqlite3_reset重置准备语句失败,将会导致sqlite3_ step返回SQLITE_MISUSE,但是在V3. 6.23.1以后,sqlite3_step()将会自动调用sqlite3_reset。

  说明:
  当一条语句被 sqlite3_prepare() 或其相关的函数预编译后, sqlite3_step() 必须被调用一次或多次来评估该预编译语句。
  该函数的详细行为依赖于由 sqlite3_prepare()(或其相关的函数) 产生的是一条怎样的预编译语句。

  函数将返回一个以下的结果来标识其执行结果:
     SQLITE_BUSY:忙碌. 数据库引擎无法锁定数据去完成其工作. 但可以多次尝试.
     SQLITE_DONE:完成. sql 语句已经被成功地执行. 在调用 sqlite_reset() 之前, 当前预编译的语句不应该被 sqlite3_step() 再次调用.
  SQLITE_ROW:查询时产生了结果. 此时可以通过相关的"数据访问函数(column access functions)"来取得数据. sqlite3_step() 的再一次调用将取得下一条查询结果.
  SQLITE_ERROR:发生了错误. 此时可以通过 sqlite3_errmmsg() 取得相关的错误信息. sqlite3_step() 不能被再次调用.
  SQLITE_MISUSE:不正确的库的使用. 该函数使用不当.

5.int sqlite3_reset(sqlite3_stmt *pStmt)

  sqlite3_reset用于重置一个准备语句对象到它的初始状态,然后准备被重新执行。所有sql语句变量使用sqlite3_bind*绑定值,使用sqlite3_clear_bindings重设这些绑定。Sqlite3_reset接口重置准备语句到它代码开始的时候。sqlite3_reset并不改变在准备语句上的任何绑定值,那么这里猜测,可能是语句在被执行的过程中发生了其他的改变,然后这个语句将它重置到绑定值的时候的那个状态。

  返回值:

  它的返回值相对有些特殊。返回SQLITE_BUSY表示暂时无法执行操作,SQLITE_DONE表示操作执行完毕,SQLITE_ROW表示执行完毕并且有返回(执行select语句时)。当返回值为SQLITE_ROW时,我们需要对查询结果进行处理,SQLITE3提供sqlite3_column_*系列函数。

const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol); 

  参数:

  iCol为列的序号,从0开始

  返回值:

  如果返回值有多行,则可以再次调用sqlite3_step函数,然后由sqlite3_column_*函数取得返回值。

6.  sqlite3_column()

  这个过程从执行sqlite3_step()执行一个准备语句得到的结果集的当前行中返回一个列。每次sqlite3_step得到一个结果集的列停下后,这个过程就可以被多次调用去查询这个行的各列的值。对列操作是有多个函数,均以sqlite3_column为前缀:

const void *sqlite3_column_blob(sqlite3_stmt*, int iCol);
int sqlite3_column_bytes(sqlite3_stmt*, int iCol);
int sqlite3_column_bytes16(sqlite3_stmt*, int iCol);
double sqlite3_column_double(sqlite3_stmt*, int iCol);
int sqlite3_column_int(sqlite3_stmt*, int iCol);
sqlite3_int64 sqlite3_column_int64(sqlite3_stmt*, int iCol);
const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol);
const void *sqlite3_column_text16(sqlite3_stmt*, int iCol);
int sqlite3_column_type(sqlite3_stmt*, int iCol);
int sqlite3_column_numeric_type(sqlite3_stmt*, int iCol);
sqlite3_value *sqlite3_column_value(sqlite3_stmt*, int iCol); 

  说明:

  第一个参数为从sqlite3_prepare返回来的prepared statement对象的指针,第二参数指定这一行中的想要被返回的列的索引。最左边的一列的索引号是0,行的列数可以使用sqlite3_colum_count()获得。

  这些过程会根据情况去转换数值的类型,sqlite内部使用sqlite3_snprintf()去自动进行这个转换,下面是关于转换的细节


内部类型


请求的类型


转换


NULL


INTEGER


结果是0


NULL


FLOAT


结果是0.0


NULL


TEXT


结果是NULL


NULL


BLOB


结果是NULL


INTEGER


FLOAT


从整形转换到浮点型


INTEGER


TEXT


整形的ASCII码显示


INTEGER


BLOB


同上


FLOAT


INTEGER


浮点型转换到整形


FLOAT


TEXT


浮点型的ASCII显示


FLOAT


BLOB


同上


TEXT


INTEGER


使用atoi()


TEXT


FLOAT


使用atof()


TEXT


BLOB


没有转换


BLOB


INTEGER


先到TEXT,然后使用atoi


BLOB


FLOAT


先到TEXT,然后使用atof


BLOB


TEXT


如果需要的话添加0终止符

备注:

   BLOB数据类型是指二进制的数据块,比如要在数据库中存放一张图片,这张图片就会以二进制形式存放,在sqlite中对应的数据类型就是BLOB

int sqlite3_column_bytes(sqlite3_stmt*, int iCol)
int sqlite3_column_bytes16(sqlite3_stmt*, int iCol)

  以上两个函数返回对应列的内容的字节数,这个字节数不包括后面类型转换过程中加上的0终止符。

  下面是几个最安全和最简单的使用策略:

  • 先sqlite3_column_text() ,然后 sqlite3_column_bytes()
  • 先sqlite3_column_blob(),然后sqlite3_column_bytes()
  • 先sqlite3_column_text16(),然后sqlite3_column_bytes16()

(1)得到数据行中某个列的数据:



sqlite3_column_xxx(sqlite3_stmt*, int iCol);
  在sqlite3_step返回SQLITE_ROW后,使用它得到第iCol列的数据。
  xxx代表:
  blob:指向保存数据内存的指针
  bytes, bytes16: 得到该blob类型数据的大小,或者text转换为UTF8/UTF16的字符串长度。
  double, int, int64: 数值
  text,text16:字符串指针
  type:该列的数据类型(SQLITE_INTEGER,SQLITE_FLOAT,SQLITE_TEXT,SQLITE_BLOB,SQLITE_NULL)
  备注:  如果对该列使用了不同与该列本身类型适合的数据读取方法,得到的数值将是转换过的结果。 

  (2)得到数据行中某个列的数据的类型:

int sqlite3_column_type(sqlite3_stmt*, int iCol);
  返回值:  SQLITE_INTEGER,SQLITE_FLOAT,SQLITE_TEXT,SQLITE_BLOB,SQLITE_NULL
  备注:  使用的方法和sqlite3_column_xxx()函数类似。 

  (3)获取列数:

int sqlite3_column_count(sqlite3_stmt *pStmt);

   返回值:

   如果过程没有返回值,如update,将返回0。

  (4)获取列名

const char *sqlite3_column_name(sqlite3_stmt*,int);

  (5)返回列数据类型

const char *sqlite3_column_decltype(sqlite3_stmt *, int i);

  (6)得到当前行中包含的数据个数



int sqlite3_data_count(sqlite3_stmt *pStmt);
  返回值:
  如果sqlite3_step返回SQLITE_ROW,可以得到列数,否则为零。 

7.int sqlite3_reset(sqlite3_stmt *pStmt)

  功能:

  重置所有绑定的值,回到刚刚调用sqlite3_prepare后的状态

8.int sqlite3_finalize(sqlite3_stmt *pStmt)

  这个过程销毁前面被sqlite3_prepare创建的准备语句,每个准备语句都必须使用这个函数去销毁以防止内存泄露。

  在空指针上调用这个函数没有什么影响,同时可以准备语句的生命周期的任一时刻调用这个函数:在语句被执行前,一次或多次调用sqlite_reset之后,或者在sqlite3_step任何调用之后不管语句是否完成执行。

  示例:

sqlite3_finalize(pStmt);
pStmt = NULL;

9.sqlite3_close

  这个过程关闭前面使用sqlite3_open打开的数据库连接,任何与这个连接相关的准备语句必须在调用这个关闭函数之前被释放。

  函数定义:

int sqlite3_close(
    sqlite3* pDB    /* 由 sqlite3_open 或基相关的函数打开的 SQLite 对象句柄 */
);

  说明:
  该函数用来析构 sqlite3 对象. 返回 SQLITE_OK 表示对象被成功析构, 以及所有相关的资源被成功回收。
  应用程序必须在关闭之前 "完成(finalize)" 所有的 "预编译语句(prepared statements)", 并且关闭所有的 "二进制句柄绑定(BLOB handle)", 如果在关闭时还有未完成的预编译语句或二进制句柄, 那么函数返回 SQLITE_BUSY(5)。
  示例:

if(pDB != NULL)
{
    sqlite3_close(pDB);
    pDB = NULL;
} 

10.sqlite3_exec

  函数定义:

int sqlite3_exec(
    sqlite3* pDB,        /* sqlite3句柄 */
    const char* sql,    /* 被执行的 SQL 语句 */
    int (*callback)(void*,int,char**,char**),  /* 执行/查询回调函数 */
    void* pvoid,    /* 传递给回调函数的第一个参数 */
    char**errmsg    /* 错误输出信息 */
);

  说明:
  该函数用来执行若干条 SQL 语句。
  该函数包裹了先前版本的 sqlite3_prepare(), sqlte3_step() 和 sqlite3_finalize() 函数, 这样, 用户就可以执行简单的代码执行多条 SQL 语句。
  sqlite3_exec()接口执行多条以";"分隔的SQL语句. 如果回调函数不为 NULL, 则它对每一个行查询结果都会调用该回调函数. 如果没有回调函数被指定, sqlite3_exec() 只是简单地忽略查询结果.
  当在执行该SQL语句发生错误时, 执行将发生中断, 并且后面的语句也全部被忽略. 如果 errmsg 参数不为空任何错误信息将会被写进由 sqlite3_malloc() 得到的的内存空间中, 即 errmsg 指向的内存. 为了避免内存泄漏, 应用程序应该在不需要该错误信息后立即调用 sqlite3_free() 释放该内存空间. 如果 errmsg 参数不为 NULL, 并且没有错误发生, errmsg 被设置为 NULL.
  如果回调函数返回非零, sqlite3_exec() 立即中断查询, 并且不再执行后续的 SQL 语句, 也不再调用回调函数, sqlite3_exec() 将返回 SQLITE_ABORT 结束执行.
  示例:

sqlite3_exec(pDB, to_utf8("delete from tablename where id=123;"), NULL, NULL, NULL);
sqlite3_exec(pDB, to_utf8("create table if not exists tablename (id integer primary key,name text);"), NULL, NULL, NULL);
sqlite3_exec(pDB, to_utf8("insert into tablename (name) values (‘女孩不哭‘);"), NULL, NULL, NULL);
if(sqlite3_exec(pDB, to_utf8("select * from tablename;"), sqlite_callback, NULL, &pszErrMsg) != SQLITE_OK)
{
  ...
  sqlite3_free(pszErrMsg);
  pszErrMsg = NULL;
}

11.sqlite3_errcode

  函数定义:

int sqlite3_errcode(
    sqlite3* pDB    /* SQLite3 数据库句柄 */
);

  说明:

   该函数返回最近一次调用 sqlite3_ API时产生的错误码。
   
示例:

int errcode = sqlite3_errcode(pDB);

12.sqlite3_errmsg

  函数定义:

const char *sqlite3_errmsg(
    sqlite3* pDB    /* SQLite3 数据库句柄 */
);

  说明:
  该函数返回与pDB数据库指针相关的错误信息, 由英语书写。
  用户不必考虑内存的释放,其由SQLite内部管理, 它也将会在下产次调用函数时被覆盖。
  示例:

printf("%s\n", sqlite3_errmsg(pDB));

13.sqlite3_key

  函数定义:

int sqlite3_key(
  sqlite3 *db,                   /* Database to be rekeyed */
  const void *pKey, int nKey     /* The key */
);

  功能:

  为加密的数据库指定密码,改函数在sqlite3_open之后调用。

14.sqlite3_rekey

  函数定义:

int sqlite3_rekey(
  sqlite3 *db,                   /* Database to be rekeyed */
  const void *pKey, int nKey     /* The new key */
);

  功能:

  重设数据库密码,如果pKey = 0 或者 nKey = 0,这数据库不加密。

15.sqlite3_get_table

  函数定义:

int sqlite3_get_table(
  sqlite3*,              /* An open database */
  const char *sql,       /* SQL to be executed */
  char ***resultp,       /* Result written to a char *[]  that this points to */
  int *nrow,             /* Number of result rows written here */
  int *ncolumn,          /* Number of result columns written here */
  char **errmsg          /* Error msg written here */
);

  功能:

查询表

参数说明

PARAM1(IN):数据库句柄
PARAM2(IN):sql语句,以\0结尾.
PARAM3(OUT):查询结果
PARAM4(OUT):返回行数(多少条数据)
PARAM5(OUT):返回列数(多少字段)
PARAM6(OUT):返回错误信息

返回值:

  SQLITE_OK 成功

16.sqlite3_free_table

  函数定义:

void sqlite3_free_table(char **result);

  功能:

  释放通过sqlite3_get_table查询保存的结果数据

  参数说明:
  PARAM1(IN):要释放的数据指针

17.sqlite3_create_function

  函数定义:

int sqlite3_create_function(
  sqlite3 *,
  const char *zFunctionName,
  int nArg,
  int eTextRep,
  void*,
  void (*xFunc)(sqlite3_context*,int,sqlite3_value**),
  void (*xStep)(sqlite3_context*,int,sqlite3_value**),
  void (*xFinal)(sqlite3_context*)
);

  功能:

   该函数用于注册/删除用户自定义函数。

18.其他

const char *sqlite3_libversion(void);
int sqlite3_libversion_number(void);          //功能:获取版本号

sqlite_int64 sqlite3_last_insert_rowid(sqlite3*);    //功能:获取最后插入的行标示.

int sqlite3_changes(sqlite3*);               //功能:获取最近执行的sqlite3_exec影响的行数.

int sqlite3_total_changes(sqlite3*);            //功能:获取自从数据库打开后有改动的函数

void sqlite3_interrupt(sqlite3*);             //功能:打断或停止数据库当前操作.

int sqlite3_complete(const char *sql);          //功能:判断语句是否以分号(;)结尾

int sqlite3_busy_handler(sqlite3*, int(*)(void*,int), void*);    //功能:设置查询忙碌时的回调处理;说明:缺省的回调函数为空,如果回调函数为空,表锁定后sqlite3_exec()执行会直接返回SQLITE_BUSY

int sqlite3_busy_timeout(sqlite3*, int ms);       //功能:设置查询超时时间(毫秒)

char *sqlite3_mprintf(const char*,...);
char *sqlite3_vmprintf(const char*, va_list);
char *sqlite3_snprintf(int,char*,const char*, ...); //功能:格式化字符,需要用%q来代替%s.(主要是不用对分号‘进行转义)

void *sqlite3_malloc(int);
void *sqlite3_realloc(void*, int);
void sqlite3_free(void*);                //功能:内存函数

int sqlite3_set_authorizer(
  sqlite3*,
  int (*xAuth)(void*,int,const char*,const char*,const char*,const char*),
  void *pUserData
);//功能:设置数据库授权

void *sqlite3_trace(sqlite3*, void(*xTrace)(void*,const char*), void*);
void *sqlite3_profile(sqlite3*,
   void(*xProfile)(void*,const char*,sqlite_uint64), void*);

void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*);    //功能:设置执行回调函数,sqlite3_exec(),sqlite3_step() ,sqlite3_get_table()时会调用

void *sqlite3_commit_hook(sqlite3*, int(*)(void*), void*);         //功能:设置事务回调函数

int sqlite3_errcode(sqlite3 *db);
const char *sqlite3_errmsg(sqlite3*);                                 //功能:获取错误码和错误消息

int sqlite3_bind_parameter_count(sqlite3_stmt*);               //功能:返回需要绑定的参数数目(sql语句中问号?数量)

const char *sqlite3_bind_parameter_name(sqlite3_stmt*, int);        //功能:获取绑定参数名字,?参数返回NULL

int sqlite3_bind_parameter_index(sqlite3_stmt*, const char *zName);   //功能:获取绑定参数索引

int sqlite3_clear_bindings(sqlite3_stmt*);                  //功能:清除绑定的参数

参考代码:

#include <stdio.h>
#include "sqlite3.h"
int main(){
    sqlite3 *db;
    char *zErrMsg = NULL;
    int rv;
    char szSql[128] = { 0 };
    sqlite3_stmt *stmt;
    rv = sqlite3_open("test.db", &db);
    if(rv){
        fprintf(stderr, "Can‘t open database: %s\n", sqlite3_errmsg(db));
        sqlite3_close(db);
        return 1;
    }
    else
       fprintf(stderr,"sqlite3_open OK\n");
       //这里查询时,假定数据库中存在表test,并且有一列为COL1(text类型)
       strcpy(szSql,"SELECT COL1 FROM test where COL1=?");
       rv = sqlite3_prepare(db, szSql, 128, &stmt, NULL);
       if( rv != SQLITE_OK ) {
         fprintf(stderr, "sqlite3_prepare(%d): %s\n", rv, sqlite3_errmsg(db));
         return -1;
       }
       rv = sqlite3_bind_text(stmt, 1, "VALUE1", strlen("VALUE1"), SQLITE_STATIC);
       if( rv != SQLITE_OK ) {
         fprintf(stderr, "sqlite3_bind_text(%d): %s\n", rv, sqlite3_errmsg(db));
         return -1;
       }
       rv = sqlite3_step(stmt);
       if( (rv != SQLITE_OK) && (rv != SQLITE_DONE) && (rv != SQLITE_ROW) ) {
         fprintf(stderr, "sqlite3_step(%d): %s\n", rv, sqlite3_errmsg(db));
         return -1;
       }
       while( rv == SQLITE_ROW ){
          fprintf(stderr, "result: %s\n", sqlite3_column_text(stmt,0));
          rv = sqlite3_step(stmt);
       }
       rv = sqlite3_finalize(stmt);
       if( rv != SQLITE_OK ) {
         fprintf(stderr, "sqlite3_finalize(%d): %s\n", rv, sqlite3_errmsg(db));
         return -1;
       }
       sqlite3_close(db);
       return 0;
}
/****************************************************************************/
#include "stdafx.h"
#include "sqlite3.h"
static int callback( void*NotUsed,int argc, char **argv, char **azColName)
{
     int i;
     for (i=0; i<argc; i++){
        printf ( "%s = %s/n", azColName[i], argv[i] ? argv[i] :"NULL" );
     }
     printf ( "/n" );
     return 0;
}
#define CHECK_RC(rc,szInfo,szErrMsg,db) if(rc!=SQLITE_OK) /
            { printf ( "%s error!/n" ,szInfo);/
            printf ( "%s/n",szErrMsg);    /
            sqlite3_free(szErrMsg);         /
            sqlite3_close(db);              /
            return 0;}
int _tmain( int argc, _TCHAR* argv[])
{
     sqlite3 *db;
     char *dbPath= "f:/test.db";
     char *szErrMsg = 0;

     int rc= sqlite3_open(dbPath, &db);
     CHECK_RC(rc, "open database" ,db);
     char *szSql= "create table UserInfo(ID int primary key , UserName char, PassWord char);";
     rc=sqlite3_exec(db,szSql,0,0,&szErrMsg);
     CHECK_RC(rc, "create table" ,szErrMsg,db);
     rc=sqlite3_exec(db, "insert into UserInfo(ID,UserName,PassWord) values(1,‘kfqcome‘,‘123456‘)",0,0,&szErrMsg);
     CHECK_RC(rc, "insert info" ,szErrMsg,db);
     rc=sqlite3_exec(db, "insert into UserInfo(ID,UserName,PassWord) values(2,‘miss wang‘,‘654321‘)",0,0,&szErrMsg);
     CHECK_RC(rc, "insert info" ,szErrMsg,db);
     szSql= "select * from UserInfo" ;
     rc = sqlite3_exec(db,szSql, callback, 0, &szErrMsg);
     CHECK_RC(rc, "query values" ,szErrMsg,db);
     sqlite3_close(db);
     getchar ();
     return 0;
}

输出结果

ID = 1
UserName = kfqcome
PassWord = 123456

ID = 2
UserName = miss wang
PassWord = 654321

程序示例

CREATE TABLE sqlite_master (
  type TEXT,
  name TEXT,
  tbl_name TEXT,
  rootpage INTEGER,
  sql TEXT
);

//获取Sqlite数据库中的表名和字段名
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent:@"database_name"];  

sqlite3 *database;
sqlite3_open([path UTF8String], &database);  

charchar *errorMsg;
const charchar *createSQL = "CREATE TABLE IF NOT EXISTS PEOPLE (ID INTEGER PRIMARY KEY AUTOINCREMENT, FIELD_DATA TEXT)";
int result = sqlite3_exec(database, createSQL, NULL, NULL, &errorMsg);  

sqlite3_stmt *statement;
if (result == SQLITE_OK) {
  const charchar *getTableInfo = "select * from sqlite_master where type=‘table‘ order by name;";
  result = sqlite3_prepare_v2(database, getTableInfo, -1, &statement, nil);
  while (sqlite3_step(statement) == SQLITE_ROW) {
    charchar *nameData = (charchar *)sqlite3_column_text(statement, 1);
    NSString *tableName = [[NSString alloc] initWithUTF8String:nameData];
    NSLog(@"name:%@",tableName);
  }  

  const charchar *getColumn = "PRAGMA table_info(PEOPLE)";
  result = sqlite3_prepare_v2(database, getColumn, -1, &statement, nil);
  while (sqlite3_step(statement) == SQLITE_ROW) {
    charchar *nameData = (charchar *)sqlite3_column_text(statement, 1);
    NSString *columnName = [[NSString alloc] initWithUTF8String:nameData];
    NSLog(@"columnName:%@",columnName);
  }  

  sqlite3_finalize(statement);
}
sqlite3_close(database);  
时间: 2024-09-29 08:49:25

SQLite剖析之编程接口详解的相关文章

.NET深入解析LINQ框架(五:IQueryable、IQueryProvider接口详解)

阅读目录: 1.环路执行对象模型.碎片化执行模型(假递归式调用) 2.N层对象执行模型(纵横向对比链式扩展方法) 3.LINQ查询表达式和链式查询方法其实都是空壳子 4.详细的对象结构图(对象的执行原理) 5.IQueryable<T>与IQueryProvider一对一的关系能否改成一对多的关系 6.完整的自定义查询 1]. 环路执行对象模型.碎片化执行模型(假递归式调用) 这个主题扯的可能有点远,但是它关系着整个LINQ框架的设计结构,至少在我还没有搞懂LINQ的本意之前,在我脑海里一直频

JDBC常用接口详解

JDBC中常用接口详解 ***DriverManager 第一.注册驱动 第一种方式:DriverManager.registerDriver(new com.mysql.jdbc.Driver()); 一.查看Driver的源代码可以看到,如果采用此种方式,会导致驱动程序注册两次,也就是在内存中会有两个Driver对象. 二.程序依赖mysql的api,脱离mysql的jar包,程序将无法编译,将来程序切换底层数据库将会非常麻烦. 第二种方式:Class.forName("com.mysql.

好消息:《Java网络编程核心技术详解》出版

2019年5月从美国回到上海,由于一切都不安定,先在旅馆里宅了4个多月,写完<精通JPA与Hibernate:Java对象持久化技术详解>,就开始写这本书.现在,正是新冠病毒疫情还没结束之际,本书克服种种困难,如期和读者见面了. 我们一不小心,就会被一种潜在的观念暗示:只要忙过了这一阵,将来就能过上高枕无忧的生活.实际上,生活中总是有各种意外的事情发生,小到个人家庭的琐事,大到国家社会的暂时的不安定.为了能随遇而安,就得常常給自己洗脑,不要以为忙过了这一阵,就会有永远太平安宁的出头之日. 戒骄

Java6.0中Comparable接口与Comparator接口详解

Java6.0中Comparable接口与Comparator接口详解 说到现在,读者应该对Comparable接口有了大概的了解,但是为什么又要有一个Comparator接口呢?难道Java的开发者都吃饱撑着没事做吗? 再谈Comparator接口之前,大家应该先了解一个叫“策略模式”的东东.一下是百度百科对策略模式的描写: 策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换.策略模式让算法独立于使用它的客户而独立变化.(原文:The Strategy Pattern

PHP Socket 编程过程详解

PHP Socket 编程过程详解 Socket用于进程间通信.进程间通信通常基于客户端—服务端模型.此时,客户端—服务端是可以彼此交互的应用程序.客户端和服务端之间的交互需要连接.Socket编程负责的就是为应用程序之间建立可进行交互的连接. 在本文中,我们将学习如何用PHP创建一个简单的客户端—服务端.我们还将学习如何客户端应用程序如何发送消息到服务端,以及如何从服务端接受消息. 使用代码 目的:开发一个客户端用于发送string消息到服务端,服务端将相同的信息反转后返回给客户端. PHP服

Android Environment类的接口详解

Android应用开发中,常使用Environment类去获取外部存储目录,在访问外部存储之前一定要先判断外部存储是否已经是可使用(已挂载&可使用)状态, 并且需要在AndroidManifest.xml文件中添加外部存储读和写的权限. Environment类中提供了几个静态常量用于标识外部存储的状态,这些状态都是String类型 MEDIA_BAD_REMOVAL 在没有挂载前存储媒体已经被移除. MEDIA_CHECKING 正在检查存储媒体. MEDIA_MOUNTED 存储媒体已经挂载

CUDA C 编程指导(二):CUDA编程模型详解

CUDA编程模型详解 本文以vectorAdd为例,通过描述C在CUDA中的使用(vectorAdd这个例子可以在CUDA sample中找到.)来介绍CUDA编程模型的主要概念.CUDA C的进一步描述可以参考<Programming Interface>. 主要内容包括: 1.Kernels(核函数) 2.Thread Hierarchy(线程结构) 3.Memory Hierarchy(存储结构) 4.Heterogeneous Programming(异构编程) 5.Compute C

嵌入式开发平台 迅为6818开发板接口详解

迅为八核iTOP-6818开发板接口详解: iTOP-4418接口图: iTOP-6818核心板: iTOP-6818开发板接口详解: 1.POWER电源接口 电源输入为5V/2A+,给核心板AXP228电源管理芯片提供5V电源,给底板供电. 2. SWITCH电源开关 轻触电源开关可以控制开发板电源通断. 3. 拨码开关 3位拨码开关控制4418启动模式. 4. 模数转换 A/D模数转换,调整滑动变阻器,模拟量可以通过转换口检测到. 5. JTAG接口 保留JTAG接口,有需要的用户可以进行扩

IDisposable接口详解

IDisposable接口详解 1. MSDN中关于这个接口的说明 [ComVisible(true)] public interface IDisposable {     // Methods     void Dispose(); } [ComVisible(true)]:指示该托管类型对 COM 是可见的.此接口的主要用途是释放非托管资源.当不再使用托管对象时,垃圾回收器会自动释放分配给该对象的内存.但无法预测进行垃圾回收的时间.另外,垃圾回收器对窗口句柄或打开的文件和流等非托管资源一无