sqlite 使用问题总结

目录

一、对比mysql要查询某一张表的列数

二、关于事务

三、关于同步取值接口的使用

四、sqlite3_prepare_v2, sqlite3_step

批量插入

 获取数据



​​​​​​​一对比mysql要查询某一张表的列数

Mysql: 执行下面的语句, 取第一行的第一个结果

select count(COLUMN_NAME) from information_schema.COLUMNS where TABLE_SCHEMA='test_db' and table_name='test_table';

Sqlite:  执行下面的语句,取查询到的行数

PRAGMA table_info(test_table); 

关于事务

SQLite 缺省为每个更新操作启动一个事务,ExecuteNonQuery方法执行时自己提交了更新事务,默认执行更新操作是会自动提交事务的,也就是说默认情况下一条更新SQL语句就是一个事务。它以文件的形式存在磁盘中,每次访问时都要打开一次文件,如果对数据库进行大量的操作,就很慢。

默认情况下,批量插入数据时,那么每一条insert都会更新事务,这样会花大量的时间处理事务,这种情况下,批量插入50000条数据,花开了1个小时,很夸张。

解决:显示启动事务。这样批量插入数据,把所有的更新SQL放在一个事务中,只有执行到Commit方法时才提交事务。用事物的形式提交,因为开始事务后,进行的大量操作语句都保存在内存中,当提交时才全部写入数据库.

{

        sqlite3_exec(db , “begin” , 0 , 0 , & zErrorMsg);

        ...

        批量插入数据

        ...

        sqlite3_exec( db , “commit” , 0 , 0 , & zErrorMsg);

}

而在启动事物以后所需要的时间直接变成不到2秒!

关于同步取值接口的使用

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

SQLITE_API void sqlite3_free_table(char **result);
  1. 上边的两个函数要配对使用,sqlite3_free_table释放获得的表空间。
  2. 获取的行数和列数为实际查询到记录
  3. pazResult 可以认为是一个指针数据,每个元素是一个字符串,长度为(nRow + 1)* nColumn,比实际查询到的数据多nColumn 个数据。多的这nColumn 是每个字段的名字,在pazResult 的前部分。
  4. 获得数据可能为空值。

下面是查询示例:

四、sqlite3_prepare_v2, sqlite3_step

int sqlite3_prepare_v2
( 
	sqlite3*db, 			/* Database handle(数据库指针) */ 
	const char*zSql, 		/* SQL statement, UTF-8encoded(使用UTF-8编码的SQL语句) */ 
	int nByte,		 	/* Maximum length of zSql inbytes.(如果nByte小于0,则函数						取出zSql中从开始到第一个0终止符的内容;如果nByte为非						负数,那么它就是这个函数能从zSql中读取的最大字节数。zSql						在第一次遇见/000或u000的时候终止) */ 
	sqlite3_stmt *ppStmt, 	/ *OUT:Statement handle(能够使用sqlite3_step()执行的编译好						的准备语句的指针,如果错误发生,它被置为NULL,例如输入						一个不正确的sql语句。调用过程必须负责在编译好的sql语句						完成使用后,调用sqlite3_finalize()删除它。 */ 
	const char**pzTail 	/* OUT: Pointer to unusedportion of zSql(当zSql在遇见终止符						或者达到设定的nByte结束后,如果还有剩余的内容,那么这						些剩余的内容将被存放到pzTail中,不包含终止符) */ 
); 
SQLITE_API int sqlite3_step(sqlite3_stmt*); 

SQLITE_API int sqlite3_finalize(sqlite3_stmt *pStmt);

sqlite3_prepare_v2 函数根据sql语句生成sqlite3_stmt这个数据对象,按照官方解释说法是这样的:sqlite3_stmt是C接口中“准备语句对象”,该对象是一条SQL语句的实例,而且该语句已经编译成二进制形式,可以直接进行计算。

  当执行sqlite3_exec时,数据库先把sql语句字符串(就是普通的字符串)进行解析,然后再编译,然后再执行,基本上需要这3个步骤。

  引入sqlite3_stmt数据结构后,sqlite3_stmt是可以结合变量使用的,也就是可以通过变量实现相同操作的循环,这个时候,sqlite3_stmt结构通过sqlite3_prepare_v2函数,可以实现对sql语句(模板)的解析和编译,生成了可以被执行的 sql语句实例,那么后面我们只需要通过sqlite3_bind_xx函数去绑定赋值变量,通过sqlite3_step进行执行,相比较使用sqlite3_exec函数,sql语句的解析和编译只执行了一次,而sqlite3_step执行多次,整体的效率势必大大提升。

批量插入

SQLITE_API int sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*));
SQLITE_API int sqlite3_bind_blob64(sqlite3_stmt*, int, const void*, sqlite3_uint64, void(*)(void*));
SQLITE_API int sqlite3_bind_double(sqlite3_stmt*, int, double);
SQLITE_API int sqlite3_bind_int(sqlite3_stmt*, int, int);
SQLITE_API int sqlite3_bind_int64(sqlite3_stmt*, int, sqlite3_int64);
SQLITE_API int sqlite3_bind_null(sqlite3_stmt*, int);
SQLITE_API int sqlite3_bind_text(sqlite3_stmt*,int,const char*,int,void(*)(void*));
SQLITE_API int sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int, void(*)(void*));
SQLITE_API int sqlite3_bind_text64(sqlite3_stmt*, int, const char*, sqlite3_uint64, void(*)(void*), unsigned char encoding);
SQLITE_API int sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*);
SQLITE_API int sqlite3_bind_pointer(sqlite3_stmt*, int, void*, const char*,void(*)(void*));
SQLITE_API int sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n);
SQLITE_API int sqlite3_bind_zeroblob64(sqlite3_stmt*, int, sqlite3_uint64);

获取数据

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


凡是过往,即为序章  

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值