当前位置:   article > 正文

sqlite3数据库高效API(六)_sqlite3_open_v2

sqlite3_open_v2
  1. sqlite3_open_v2
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 */
)

参数1:sqlite数据库文件名;

参数2:输出参数,数据库句柄;

参数3:标志,如下:

/* Ok for sqlite3_open_v2() 只读模式打开,若数据库不存在,则返回错误*/
#define SQLITE_OPEN_READONLY 0x00000001

/* Ok for sqlite3_open_v2() 若可能,将打开数据库进行读写,或仅在文件受操作系统写保护时才进行读取;这两种情况下数据库必须依据存在,否则返回错误;*/
#define SQLITE_OPEN_READWRITE 0x00000002

/* Ok for sqlite3_open_v2() 数据库不存则创建*/
#define SQLITE_OPEN_CREATE 0x00000004
#define SQLITE_OPEN_DELETEONCLOSE 0x00000008 /* VFS only */
#define SQLITE_OPEN_EXCLUSIVE 0x00000010 /* VFS only */
#define SQLITE_OPEN_AUTOPROXY 0x00000020 /* VFS only */

/* Ok for sqlite3_open_v2() 若设置了此标志,则文件名可解释成URL */
#define SQLITE_OPEN_URI 0x00000040

/* Ok for sqlite3_open_v2() 数据库将作为内存数据库打开;*/
#define SQLITE_OPEN_MEMORY 0x00000080
#define SQLITE_OPEN_MAIN_DB 0x00000100 /* VFS only */
#define SQLITE_OPEN_TEMP_DB 0x00000200 /* VFS only */
#define SQLITE_OPEN_TRANSIENT_DB 0x00000400 /* VFS only */
#define SQLITE_OPEN_MAIN_JOURNAL 0x00000800 /* VFS only */
#define SQLITE_OPEN_TEMP_JOURNAL 0x00001000 /* VFS only */
#define SQLITE_OPEN_SUBJOURNAL 0x00002000 /* VFS only */
#define SQLITE_OPEN_MASTER_JOURNAL 0x00004000 /* VFS only */

/* Ok for sqlite3_open_v2() 新的数据库连接将使用"多线程模式".意味着运行单独的线程同时使用SQLite,只要每个线程使用不同数据库连接;*/
#define SQLITE_OPEN_NOMUTEX 0x00008000

/* Ok for sqlite3_open_v2() 新的数据库将使用"序列化"线程模式;意味多个线程可以安全的尝试同时使用同一数据库连接;*/
#define SQLITE_OPEN_FULLMUTEX 0x00010000

/* Ok for sqlite3_open_v2() 数据库已启用共享缓存;*/
#define SQLITE_OPEN_SHAREDCACHE 0x00020000

/* Ok for sqlite3_open_v2() 数据库被打开共享缓存禁用;*/
#define SQLITE_OPEN_PRIVATECACHE 0x00040000
#define SQLITE_OPEN_WAL 0x00080000 /* VFS only */

参数4:sqlite3_vfs对象的名称,该对象定义了新数据库连接应该使用的操作系统接口; NULL表示使用默认的sqlite3_vfs对象;

  1. sqlite3_prepare_v2
int sqlite3_prepare_v2(
sqlite3 *db, /* Database handle. */
const char *zSql, /* UTF-8 encoded SQL statement. */
int nBytes, /* Length of zSql in bytes. */
sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */
const char **pzTail /* OUT: End of parsed string */
)

首选sqlite3_prepare_v2( ); sqlite3_prepare( )接口是遗留的,应该避免; sqlite3_prepare_v3( )有一个二外的"prepFlags"选项,用于特殊用途;

参数1:sqlite3_open_v2等获取的数据句柄;

参数2:utf8编码格式的sql语句;

参数3:nBytes<0,则zSql被读取到第一个零终止符; nBytes=0,不会生成任何准备好的语句;nBytes>0,表示从zSql语句读取的字节数;

参数4:ppStmt指向一个编译好的准备好的语句,可以使用sqlite3_step()执行; 若参数2输入的文本不包含SQL(输入的是空字符串或注释),则*ppStmt设置为NULL; 调用过程负责在编译完成后使用sqlite3_finalize()删除已编译的SQL语句;

返回值:指向成功返回SQLITE_OK;

  1. sqlite3_bind_xxx

将值绑定到准备好的语句

  1. int sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*));
  2. int sqlite3_bind_double(sqlite3_stmt*, int, double);
  3. int sqlite3_bind_int(sqlite3_stmt*, int, int);
  4. int sqlite3_bind_int64(sqlite3_stmt*, int, sqlite3_int64);
  5. int sqlite3_bind_null(sqlite3_stmt*, int);
  6. int sqlite3_bind_text(sqlite3_stmt*,int,const char*,int,void(*)(void*));
  7. int sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*);
  8. int sqlite3_bind_pointer(sqlite3_stmt*, int, void*, const char*,void(*)(void*));
  9. int sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n);

参数1: 由sqlite3_prepare_v2()返回的sqlite3_stmt对象的指针;

参数2: 要设置的sql参数的索引;最左的sql参数的索引为1;当多次使用同一个命名的sql参数时,第二次和后续出现的索引与第一次出现的索引相同; 填1即可;

参数3: 要绑定到参数的值;若上述有该参数的是NULL指针,则忽略参数4;结果与sqlite3_bind_null相同;

参数4: 是参数3的字节数(字节而不是字符)

参数5:指示或控制参数3引用的对象的生存期; (1)可以传递一个析构函数,在sqlite处理完blob或字符串后处理它;即使对绑定API的调用失败,也会调用该函数来处理blob或字符串,但若参数3为NULL指针或参数4为负数,则不会调用析构函数; (2)可以传递常量SQLITE_STATIC,以知识应用程序任然负责处理对象;这种情况下,对象及其提供的指针必须保持有效,直到完成准备好的语句或将同一sql参数绑定到其他对象; (3)可以传递常量SQLITE_TRANSENT,以指示从sqlite3_bind_* 返回之前复制对象;

返回值: 成功返回SQLITE_OK;

  1. sqlite3_step
int sqlite3_step(sqlite3_stmt*);

在使用了sqlite3_prepare_v2()等准备好语句后,必须调用一次或多次该函数来评估sqlite语句;

SQLITE_DONE表示语句已经成功执行完毕;

  1. sqlite3_finalize
int sqlite3_finalize(sqlite3_stmt *pStmt);

调用sqlite3_finalize()函数以删除准备好的语句;

若最近换一次求值没有遇到错误,或者从未对语句求值 ,则sqlite3_finalize()返回SQLITE_OK;

6. 返回错误码

如果字符串或BLOB的大小超过sqlite3_limit(SQLITE_limit_LENGTH)或SQLITE_MAX_LENGTH所施加的限制,则可能返回SQLITE_TOOBIG。

如果参数索引超出范围,则返回SQLITE_RANGE。

如果malloc()失败,则返回SQLITE_NOMEM。

7. 查询相关API
const void *sqlite3_column_blob(sqlite3_stmt*, int iCol); double sqlite3_column_double(sqlite3_stmt*, int iCol); int sqlite3_column_int(sqlite3_stmt*, int iCol); const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol); sqlite3_value *sqlite3_column_value(sqlite3_stmt*, int iCol); int sqlite3_column_bytes(sqlite3_stmt*, int iCol); int sqlite3_column_type(sqlite3_stmt*, int iCol);

上述例程返回有关查询的当前结果行的当个列的信息; 在每一种情况下,第一个参数都是一个sqlite3_stmt指针,由sqlite3_prepare_v2()获取; 第二个参数是返回其列的索引,结果最左侧的列的索引为0; 可以由sqlite3_column_count()确定结果中的列数;

若SQL语句当前未指向有效行,或者列索引超出范围,则结果未定义;只有在最近一次对sqlite3_step()的调用返回SQLITE_ROW并且既没有调用sqlite3_reset(),也没有调用sqlite3_finalize()时,才调用这些例程;

sqlite3_column_type()返回结果列的初始数据类型的数据类型代码;值是SQLITE_INTEGER、SQLITE_FLOAT、SQLITE_TEXT、SQLITE_BLOB或SQLITE_NULL之一;

若结果是BLOB或utf-8字符串,则sqlite3_column_bytes()接口来确定该BLOB或字符串的大小;返回的值是字符串的字节数而不是字符数;

8. 示例
  1. #include <sqlite3.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <time.h>
  5. #include <unistd.h>
  6. #include <string.h>
  7. // 一条速度 信息
  8. struct dr_speed_t
  9. {
  10. time_t start_time; // 时间
  11. unsigned char speed; // 平均速度
  12. unsigned char state; // 状态信息
  13. unsigned char reserved[2];
  14. };
  15. static sqlite3 *g_db = NULL;
  16. //typedef int (*sqlite3_callback)(void*,int,char**, char**);
  17. static int count_callback(void *args, int nCol, char **rowArr, char **colName)
  18. {
  19. int *total_size = (int *)args;
  20. *total_size = atoi(*rowArr);
  21. return 0;
  22. }
  23. static int create_callback(void *args, int nCol, char **rowArr, char **colName)
  24. {
  25. sqlite3 *db = (sqlite3 *)args;
  26. printf("nCol = %d %s \n",nCol, rowArr[0]);
  27. if(atoi(rowArr[0]) < 1){
  28. char sql[128], *err;
  29. int ret;
  30. snprintf(sql, sizeof(sql), "create table %s(tim INTEGER primary key, type INTEGER, bval blob)", "tab_product");
  31. ret = sqlite3_exec(db, sql, 0, 0, &err);
  32. if(ret != SQLITE_OK){
  33. if(err){
  34. sqlite3_free(err);
  35. return -1;
  36. }
  37. }
  38. }
  39. return 0;
  40. }
  41. int SqlSave(time_t tim, void *extData, int dataLen)
  42. {
  43. char sql[128] = {0};
  44. char *err = NULL;
  45. int ret ;
  46. sqlite3_stmt *stmt = NULL;
  47. snprintf(sql, sizeof(sql),"replace into %s(tim,type,bval) values(%ld,%d,?)","tab_product",tim,0);
  48. ret = sqlite3_prepare_v2(g_db, sql, -1, &stmt, NULL);
  49. if(ret != SQLITE_OK){
  50. printf("sqlite3_prepare_v2 err\n");
  51. return -1;
  52. }
  53. ret = sqlite3_bind_blob(stmt, 1, extData, dataLen, NULL);
  54. if(ret != SQLITE_OK){
  55. goto ERR;
  56. }
  57. ret = sqlite3_step(stmt);
  58. if(ret != SQLITE_OK){
  59. goto ERR;
  60. }
  61. sqlite3_finalize(stmt);
  62. return 0;
  63. ERR:
  64. sqlite3_finalize(stmt);
  65. return -1;
  66. }
  67. int SqlQueryCount(time_t start_time, time_t end_time)
  68. {
  69. char sql[256], *err;
  70. int ret;
  71. int total_size = 0;
  72. snprintf(sql, sizeof(sql), "select count(*) from %s where tim >= %ld and tim < %ld", "tab_product", start_time, end_time);
  73. ret = sqlite3_exec(g_db, sql, count_callback, &total_size, &err);
  74. if(ret != SQLITE_OK){
  75. printf("sqlite3_exec err\n");
  76. return -1;
  77. }
  78. return total_size;
  79. }
  80. int SqlQuerySpeed(time_t start_time, time_t end_time)
  81. {
  82. char sql[128] = {0};
  83. char *err = NULL;
  84. int ret ;
  85. printf("query count = %d\n",SqlQueryCount(start_time, end_time));
  86. sqlite3_stmt *stmt = NULL;
  87. snprintf(sql, sizeof(sql),"select * from %s where tim > %ld and tim < %ld order by tim desc","tab_product",start_time, end_time);
  88. ret = sqlite3_prepare_v2(g_db, sql, -1, &stmt, NULL);
  89. if(ret != SQLITE_OK){
  90. printf("sqlite3_prepare_v2 err\n");
  91. return -1;
  92. }
  93. while(1)
  94. {
  95. ret = sqlite3_step(stmt);
  96. if(ret != SQLITE_ROW){
  97. printf("query exit\n");
  98. break;
  99. }
  100. time_t tim = sqlite3_column_int(stmt, 0);
  101. int type = sqlite3_column_int(stmt, 1);
  102. struct dr_speed_t *speed = (struct dr_speed_t *)sqlite3_column_blob(stmt, 2);
  103. int blob_len = sqlite3_column_bytes(stmt, 2);
  104. if(blob_len != sizeof(struct dr_speed_t)){
  105. printf("--> query err\n");
  106. }
  107. printf("speed=%d time=%ld state=%d\n",speed->speed,speed->start_time,speed->state);
  108. }
  109. sqlite3_finalize(stmt);
  110. return 0;
  111. }
  112. int main(int argc, const char *argv[])
  113. {
  114. char sql[128] = {0};
  115. char *err = NULL;
  116. int ret ;
  117. //读写,不存在则创建,多线程访问;
  118. ret = sqlite3_open_v2("./config.db", &g_db, SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|SQLITE_OPEN_FULLMUTEX, NULL);
  119. if(ret != SQLITE_OK){
  120. printf("sqlite_open_v2 err\n");
  121. return -1;
  122. }
  123. //检查数据表是否存在,不存在回调里创建
  124. snprintf(sql,sizeof(sql),"select count(*) from sqlite_master where type='table' and name='%s'","tab_product");
  125. ret = sqlite3_exec(g_db, sql, create_callback, g_db, &err);
  126. if(ret != SQLITE_OK){
  127. sqlite3_free(err);
  128. sqlite3_close_v2(g_db);
  129. }
  130. //保存100次数据,正常情况下单次保存;
  131. struct dr_speed_t speed;
  132. time_t t = time(NULL);
  133. for(int i = 0; i < 100; ++i){
  134. memset(&speed, 0, sizeof(struct dr_speed_t));
  135. speed.speed = i;
  136. speed.start_time = t/1000 + i;
  137. speed.state = ((i % 2) == 0) ? 0 : 1;
  138. SqlSave(speed.start_time,&speed,sizeof(struct dr_speed_t));
  139. }
  140. sleep(1);
  141. //批量查询
  142. SqlQuerySpeed(0, time(NULL));
  143. sqlite3_close_v2(g_db);
  144. return 0;
  145. }
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/490879
推荐阅读
相关标签
  

闽ICP备14008679号