参数绑定:
和大多数关系型数据库一样,sqlite的sql文本也支持变量绑定,以便减少sql语句被动态
解析的次数,从而提高数据查询和数据操作的效率。要完成该操作,我们需要使用sqlite提
供的另外两个接口APIs,sqlite3_reset和sqlite3_bind。
见如下示例:
void test_parameter_binding() {
//1. 不带参数绑定的情况下插入多条数据。
char strsql[128];
for (int i = 0; i < MAX_ROWS; ++i) {
sprintf(strsql,"insert into testtable values(%d)",i);
sqlite3_prepare_v2(...,strsql);
sqlite3_step(prepared_stmt);
sqlite3_finalize(prepared_stmt);
}
//2. 参数绑定的情况下插入多条数据。
string strsqlWithParameter = "insert into testtable values(?)";
sqlite3_prepare_v2(...,strsql);
for (int i = 0; i < MAX_ROWS; ++i) {
sqlite3_bind(...,i);
sqlite3_step(prepared_stmt);
sqlite3_reset(prepared_stmt);
}
sqlite3_finalize(prepared_stmt);
}
这里首先需要说明的是,sql语句"insert into testtable values(?)"中的问号(?)表示参数变量的
占位符,该规则在很多关系型数据库中都是一致的,因此这对于数据库移植操作还是比较方便
的。
通过上面的示例代码可以显而易见的看出,参数绑定写法的执行效率要高于每次生成不同的
sql语句的写法,即2)在效率上要明显优于1),下面是针对这两种写法的具体比较:
1. 单单从程序表面来看,前者在for循环中执行了更多的任务,比如字符串的填充、sql语句
的prepare,以及prepared_statement对象的释放。
2. 在sqlite的官方文档中明确的指出,sqlite3_prepare_v2的执行效率往往要低于
sqlite3_step的效率。
3. 当插入的数据量较大时,后者带来的效率提升还是相当可观的。
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);
例程:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sqlite3.h>
static sqlite3 *db;
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;
}
sqlite3 *db_connect(char *db_name)
{
int rc;
rc = sqlite3_open(db_name,&db);
return db;
}
int db_exec_stmt(char *sql)
{
int rc;
char *zErrMsg = 0;
rc = sqlite3_exec(db,sql,callback,&zErrMsg);
if( rc!=sqlITE_OK ){
fprintf(stderr,"sql error: %s\n",zErrMsg);
sqlite3_free(zErrMsg);
exit(1);
}
return 0;
}
void db_exec()
{
char *sql = "insert into user_info (id,user_name) values(?,?)";
sqlite3_stmt *stmt;
const char *tail;
int i;
int ncols;
int rc;
char *name="xiaoliang";
rc = sqlite3_prepare(db,strlen(sql),NULL);
if (rc != sqlITE_OK)
{
fprintf(stderr,"sql error:%s\n",sqlite3_errmsg(db));
}
sqlite3_bind_int(stmt,20);
sqlite3_bind_text(stmt,name,strlen(name),sqlITE_STATIC);
sqlite3_step(stmt);
sqlite3_finalize(stmt);
}
int main(int argc,char **argv)
{
char *db_name="test.db";
db = db_connect(db_name);
// rc = db_exec_stmt(sql);
db_exec();
sqlite3_close(db);
return 0;
}