http://www.sqlite.org/cintro.html
所有的函数在这里都可以看到。
打开一个数据库
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 */
);
const char *filename :指数据库名称。
然后传递一个**ppDb,而返回的连接句柄保存在*ppDb,所以我们声明一个sqlite3 *ppDb指针,传递进去&ppDb
若用sqlite3_open_v2,那么多了两个参数,其中flags的解释在http://www.sqlite.org/c3ref/c_open_autoproxy.html
SQLITE_OPEN_NOMUTEX
,SQLITE_OPEN_FULLMUTEX
,SQLITE_OPEN_SHAREDCACHE
and/or SQLITE_OPEN_PRIVATECACHE
- QLITE_OPEN_READONLY
- The database is opened in read-only mode. If the database does not already exist,an error is returned.
- SQLITE_OPEN_READWRITE
- The database is opened for reading and writing if possible,or reading only if the file is write protected by the operating system. In either case the database must already exist,otherwise an error is returned.
- SQLITE_OPEN_READWRITE| SQLITE_OPEN_CREATE
- The database is opened for reading and writing,and is creates it if it does not already exist. This is the behavior that is always used for sqlite3_open() and sqlite3_open16().
第四个参数通常是null,选择默认的。
通常的做法是:
sqlite3 * db;
int result;
char * errmsg = NULL;
result = sqlite3_open("/ebframe/data/ebframe.db",&db );
if( result != sqlITE_OK )
{
fprintf(stderr,"Can't open database: %s",sqlite3_errmsg(db));
sqlite3_close(db);
return -1;
}
千万不要忘记在最后sqlite3_close(db);
sqlite3_prepare()
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 */
);
int sqlite3_prepare_v2(
sqlite3 *db,/* OUT: Statement handle */
const char **pzTail /* OUT: Pointer to unused portion of zsql */
);
官方文档推荐用sqlite3_prepare_v2(),因为这个函数有很多的好处。细节看http://www.sqlite.org/c3ref/prepare.html
sqlite3 *db,这个就不解释了
const char *zsql 这个是要编译的zsql语句,实际是个字符串 select * from table;
int nByte 若nByte<0,那么zsql将读到第一个'/0',若nByte>0,那么他就是读取nByte的数量,或者在'/0'结束
sqlite3_stmt **ppStmt ;声明的时候,声明sqlite3_stmt *ppStmt ,传递&ppStmt ,*ppStmt 指向编译好的zsql语句,这个语句将要被
sqlite3_step() 执行,发生错误时ppStmt 被置为NULL。
成功执行函数返回: SQLITE_OK ,错误发生返回error,每个error定义在http://www.sqlite.org/c3ref/c_abort.html
sqlite3_stmt *ppStmt ;
sqlite3_prepare_v2(db,"insert into table(name,age,salary)values('stone','32','3455');",-1,&ppStmt,0);
....
sqlite3_finalize(stmt); 最后一步析构掉。
int sqlite3_step(sqlite3_stmt*)
这个函数执行sqlite3_prepare_v2()函数编译出来的结果,它每次执行只能出来一行的结果,若是还有多余的结果,那么还需要继续调用,直到语句执行完。
每执行一次,该函数将返回以下的返回值
SQLITE_BUSY:数据库忙,现在不能使用。
SQLITE_DONE:此条语句执行完毕,若想在执行这个语句,那么必须使用sqlite3_reset()将虚拟机初始化到初始阶段,这样的目的是清 除已经绑定的参数。
SQLITE_ROW:如果正在执行一条语句,返回值将是这个,这时将输出一行执行结果,可供调用者调用,我们需要继续调用sqlite3_step来产生下一行的输出,使用column access functions函数能获取到该行
SQLITE_ERROR:运行时错误,这时不能再继续调用sqlite3_step()函数了。
sqlite3_column()
- sqlite3_column_blob()
- sqlite3_column_bytes()
- sqlite3_column_bytes16()
- sqlite3_column_count()
- sqlite3_column_double()
- sqlite3_column_int()
- sqlite3_column_int64()
- sqlite3_column_text()
- sqlite3_column_text16()
- sqlite3_column_type()
- sqlite3_column_value()
具体含义看http://www.sqlite.org/c3ref/column_blob.html
每个函数都返回sqlite3_step()输出的一行的其中一列的值,这样我们就需要调用多次获取每行的值
例如
r = sqlite3_step(stmt);
int number;
int id;
const unsigned char * name;
while( r == sqlITE_ROW ){
id = sqlite3_column_int( stmt,0 );
name = sqlite3_column_text( stmt,1 );
number = sqlite3_column_int( stmt,2 );
printf("ID: %d Name: %s Age: %d /n",id,name,number);
sqlite3_step(stmt);
}
sqlite3_finalize()
int sqlite3_finalize(sqlite3_stmt *pStmt);他析构掉了由sqlite3_prepare() 生成的语句,以防止内存泄露。没执行完一条编译后的语句,都要
这么的析构下。
sqlite3_close()
关闭和打开是对应的,千万别忘记。
sqlite3_bind
和sqlite3_column一样,他也是一系列的函数,我们必须选择的用,它是用来给sqlite3_stmt *pStmt语句增加值的,对于不同类型的参数要选用不同的函数。
int sqlite3_bind_blob(sqlite3_stmt*,int,const void*,int n,void(*)(void*));
int sqlite3_bind_double(sqlite3_stmt*,double);
int sqlite3_bind_int(sqlite3_stmt*,int);
int sqlite3_bind_int64(sqlite3_stmt*,sqlite3_int64);
int sqlite3_bind_null(sqlite3_stmt*,int);
int sqlite3_bind_text(sqlite3_stmt*,const char*,void(*)(void*));
int sqlite3_bind_text16(sqlite3_stmt*,void(*)(void*));
int sqlite3_bind_value(sqlite3_stmt*,const sqlite3_value*);
int sqlite3_bind_zeroblob(sqlite3_stmt*,int n);
具体的每个用法查询http://www.sqlite.org/c3ref/bind_blob.html
下面的列子中包含了他的用法
/插入数据
sqlite3_prepare(db,
"INSERT INTO players (name,num) VALUES(?,?);",
-1,&stmt,&zTail);
char str[] = "Kevin";
int n = 23;
sqlite3_bind_text(stmt,1,str,sqlITE_STATIC); //绑定数据
sqlite3_bind_int(stmt,2,n);
r = sqlite3_step(stmt);
if( r!=sqlITE_DONE){
printf("%s",sqlite3_errmsg(db));
}
sqlite3_reset(stmt); //重新复位下stmt语句
//插入第二个数据
char str2[] = "Jack";
int n2 = 16;
sqlite3_bind_text(stmt,str2,sqlITE_STATIC);
sqlite3_bind_int(stmt,n2);
r = sqltie3_step(stmt);
if( r!=sqlITE_DONE){
printf("%s",sqlite3_errmsg(db));
}
sqltie3_finalize(stmt);
int sqlite3_reset(sqlite3_stmt *pStmt);
复位有sqlite3_bind_text绑定的语句,这样可以重新再用pstmt语句,这是为了提高运行速度。
上例子中有他的用法。
sqlite3_exec()
原型:
int sqlite3_exec(
sqlite3*,/* An open database */
const char *sql,/* sql to be evaluated */
int (*callback)(void*,char**,char**),/* Callback function */
void *,/* 1st argument to callback */
char **errmsg /* Error msg written here */
);
其中callback的原型是:
int sqlite3_exec _callback(void *data,int n_columns,char **col_values,char **col_names);
sqlite3_exec()是对一些基本sqlite3的基本包装,它使用起来更方便。有个回调函数传给sqlite3_exec()是用来处理每一个行的结果。
int sqlite3_exec_callback(void *data,int n_columns,char **col_values,char **col_names)
{
int i=0;
printf("n_columns : %d/n",n_columns);
for (i = 0; i < n_columns; i++)
{
// printf("%s/t",col_names[i]);
printf("%s/t",col_values[i]);
}
printf("/n");
printf("%s/t",col_values[i]);
printf("%s/t",col_values[i+1]);
}
sqlite3_exec(db,sql,&sqlite3_exec_callback,&errmsg);
这个挺好用,当没有返回值时,这个很好用,不需要回调函数。
说明上是只能返回一行,实际试验也是,但是网上的说能返回所有的结果,不知道为什么。这个占时不会用。
sqlite3_get_table
这个函数是个旧的接口,不推荐使用,但是却很好使用。
int sqlite3_get_table(原文链接:https://www.f2er.com/sqlite/202732.html
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 */
);
void sqlite3_free_table(char **result);
这两个函数要成对的使用。
这是个就的接口函数,是不推荐用的,但是却很方便。
假设返回了N行M列,那么共有(N+1)*M元素。结果放在pazResult,其实
pazResult是个指针数组char **pazResult,
假设我们要查的表的结果如下,此时N==3 M=2,那么共有8个结果放在pazResult
Name | Age
-----------------------
Alice | 43
Bob | 28
Cindy | 21
指针数组pazResult存放的结果如下图:
每个指针放着每行的每个列的值
azResult[0] = "Name";
azResult[1] = "Age";
azResult[2] = "Alice";
azResult[3] = "43";
azResult[4] = "Bob";
azResult[5] = "28";
azResult[6] = "Cindy";
azResult[7] = "21";
当用完这个函数后,我们必须用sqlite3_free_table释放掉之前的内存。其实这个函数是sqlite3_exec() 的包装。