[sqlite3]_[初级]_[使用正则表达式REGEXP查询]

前端之家收集整理的这篇文章主要介绍了[sqlite3]_[初级]_[使用正则表达式REGEXP查询]前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

场景

1.在一些数据库db文件中,随着版本更新可能会有不同的表名,但是这些表名一般都符合某种规则,所以适配不同版本的数据库表时,最好的办法是动态获取表名.

2.或者在查询Text数据里需要匹配某个email,某个数值,都可以用正则表达式.

说明

1.REGEXP 操作符是sqlite3的一个调用regexp()函数的特殊语法. 默认情况下没有定义这个regexp()用户函数,所以在使用REGEXP操作符时会返回一个错误信息,sqlITE_ERROR = 1. 如果在运行时定义了一个regexp函数的话,那么使用语法 X REGEXP Y 操作语句会以这样的形式调用 regexp(Y,X). regexp(zPattern,zString)

2.用户定义的regexp(Y,X)函数使用 sqlite3_create_function 创建.

  1. int sqlite3_create_function(
  2. sqlite3 *db,const char *zFunctionName,int nArg,int eTextRep,void *pApp,void (*xFunc)(sqlite3_context*,int,sqlite3_value**),void (*xStep)(sqlite3_context*,void (*xFinal)(sqlite3_context*)
  3. );@H_403_29@
  4. 3.因为我们的regexp(Y,X)只有2个参数,所以nArg的值是2. 如果 xFunc,xStep,XFinal 三个都为NULL,会删除这个用户自定义函数.

  5. db: sqlite3指针.
  6. zFunctionName: "regexp"
  7. nArg: 2
  8. eTextRep: 指定regexp参数的文本编码,一般是 sqlITE_UTF8 | sqlITE_DETERMINISTIC,sqlITE_DETERMINISTIC的意思确定性,当给同样的输入时,输出是一样的. 但是有些函数却不一样,比如random()就不是确定性的.
  9. pApp用户自定义userdata,通过 ``` void *sqlite3_user_data(sqlite3_context*) ``` 获取.
  10. xFunc: 用户自定义regexp函数指针.
  11. xStep: NULL
  12. xFinal: NULL@H_403_29@ 
  13.  

    4.void (*xFunc)(sqlite3_context*,sqlite3_value**) 函数定义里通过调用 void sqlite3_result_int(sqlite3_context*,int) 来实现返回值. 这里我们返回非0 true,0false.

  14.  

    例子

  15.  
    // test-sqlite3-regex.cpp : 定义控制台应用程序的入口点。
  16. //
  17. #include "stdafx.h"
  18. #include <Windows.h>
  19. #include <memory>
  20. #include <string>
  21. #include <algorithm>
  22. #include <regex>
  23. #include <iostream>
  24. #include <assert.h>
  25. #include "sqlite3.h"
  26. void sqlite3Regexp(sqlite3_context* context,int argc,sqlite3_value** values) {
  27.     std::cout << (const char*)sqlite3_user_data(context) << std::endl;
  28.     int ret;
  29.     std::string reg = (char*)sqlite3_value_text(values[0]);
  30.     std::string text = (char*)sqlite3_value_text(values[1]);
  31.     std::transform(text.begin(),text.end(),text.begin(),::toupper);
  32.     std::transform(reg.begin(),reg.end(),reg.begin(),::toupper);
  33.     if ( argc != 2 || reg.size() == 0 || text.size() == 0) {
  34.         sqlite3_result_error(context,"sql function regexp() called with invalid arguments.\n",-1);
  35.         return;
  36.     }
  37.     std::regex pattern(reg);
  38.     std::smatch color_match;
  39.     sqlite3_result_int(context,std::regex_search(text,color_match,pattern));
  40. }
  41. bool Testsqlite3Regexp(){
  42.     sqlite3* db = NULL;
  43.     sqlite3_stmt* query = NULL;
  44.     int ret = 0;
  45.     // 创建DB文件
  46.     // 如果不需要创建db文件,使用sqlite3_open即可
  47.     ret = sqlite3_open_v2("test.db",&db,sqlITE_OPEN_READWRITE | sqlITE_OPEN_CREATE,NULL);
  48.     if (sqlITE_OK != ret)
  49.         return false;
  50.     std::shared_ptr<sqlite3> sp_db(db,[](sqlite3* db){ 
  51.         sqlite3_close(db);
  52.     });
  53.     // 创建表
  54.     std::string create = "CREATE TABLE IF NOT EXISTS X_12PHOTO (userid INTEGER PRIMARY KEY,ipaddr"
  55.     " TEXT,username TEXT,useradd TEXT,userphone INTEGER,age INTEGER,"
  56.                                                     "time TEXT NOT NULL DEFAULT" 
  57.                                                                              " (NOW()));";
  58.     // 注意,如果使用了sqlite3_stmt不关闭的话调用sqlite3_close是返回 sqlITE_BUSY 失败的.
  59.     sqlite3_stmt *stmt = NULL;
  60.     ret = sqlite3_prepare(db,create.c_str(),create.size(),&stmt,NULL);
  61.     if(sqlITE_OK != ret)
  62.         return false;
  63.     if (sqlite3_step(stmt) != sqlITE_DONE){
  64.         sqlite3_finalize(stmt); 
  65.         return false;
  66.     }
  67.     sqlite3_finalize(stmt);
  68.     // 获取数据库匹配的表
  69.     static const char* sql = "SELECT name FROM sqlite_master WHERE type=\"table\" AND name REGEXP 'X_[0-9]+PHOTO'";
  70.     sqlite3_create_function(db,"regexp",2,sqlITE_UTF8 | sqlITE_DETERMINISTIC,(void*)sql,&sqlite3Regexp,NULL,NULL);
  71.     ret = sqlite3_prepare(db,sql,strlen(sql),NULL);
  72.     if(sqlITE_OK != ret){
  73.         return false;
  74.     }
  75.     int flag = 0;
  76.     while(sqlite3_step(stmt) == sqlITE_ROW ){
  77.         auto table_sql = (const char*)sqlite3_column_text(stmt,0);
  78.         std::cout << table_sql << std::endl;
  79.     }
  80.     sqlite3_finalize(stmt);
  81.     sqlite3_create_function(db,0,NULL);
  82.     ::DeleteFile(L"test.db");
  83.     return true;
  84. }
  85. int _tmain(int argc,_TCHAR* argv[])
  86. {
  87.     assert(Testsqlite3Regexp());
  88.     system("pause");
  89.     return 0;
  90. }@H_403_29@ 
  91.  

    输出:

  92.  
    SELECT name FROM sqlite_master WHERE type="table" AND name REGEXP 'X_[0-9]+PHOTO' X_12PHOTO @H_403_29@ 
  93.  

    参考

  94.  

    1.lang_expr
    2.create_function
    3.sqlite-in-c-and-supporting-regexp
    4.icu.c

猜你在找的Sqlite相关文章