[sqlite3]_[初级]_[使用正则表达式REGEXP查询]
2017-03-02 22:55
1146 查看
场景
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创建.
int sqlite3_create_function( sqlite3 *db, const char *zFunctionName, int nArg, int eTextRep, void *pApp, void (*xFunc)(sqlite3_context*,int,sqlite3_value**), void (*xStep)(sqlite3_context*,int,sqlite3_value**), void (*xFinal)(sqlite3_context*) );
3.因为我们的regexp(Y,X)只有2个参数,所以nArg的值是2. 如果 xFunc,xStep,XFinal 三个都为NULL,会删除这个用户自定义函数.
db: sqlite3指针. zFunctionName: "regexp" nArg: 2 eTextRep: 指定regexp参数的文本编码,一般是 SQLITE_UTF8 | SQLITE_DETERMINISTIC, SQLITE_DETERMINISTIC的意思确定性,当给同样的输入时,输出是一样的. 但是有些函数却不一样, 比如random()就不是确定性的. pApp:用户自定义userdata, 通过 ``` void *sqlite3_user_data(sqlite3_context*) ``` 获取. xFunc: 用户自定义的regexp函数指针. xStep: NULL xFinal: NULL
4.
void (*xFunc)(sqlite3_context*,int,sqlite3_value**)函数定义里通过调用
void sqlite3_result_int(sqlite3_context*, int)来实现返回值. 这里我们返回非0 为true, 0为false.
例子
// test-sqlite3-regex.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include <Windows.h> #include <memory> #include <string> #include <algorithm> #include <regex> #include <iostream> #include <assert.h> #include "sqlite3.h" void Sqlite3Regexp(sqlite3_context* context, int argc, sqlite3_value** values) { std::cout << (const char*)sqlite3_user_data(context) << std::endl; int ret; std::string reg = (char*)sqlite3_value_text(values[0]); std::string text = (char*)sqlite3_value_text(values[1]); std::transform(text.begin(),text.end(),text.begin(),::toupper); std::transform(reg.begin(),reg.end(),reg.begin(),::toupper); if ( argc != 2 || reg.size() == 0 || text.size() == 0) { sqlite3_result_error(context, "SQL function regexp() called with invalid arguments.\n", -1); return; } std::regex pattern(reg); std::smatch color_match; sqlite3_result_int(context, std::regex_search(text, color_match, pattern)); } bool TestSqlite3Regexp(){ sqlite3* db = NULL; sqlite3_stmt* query = NULL; int ret = 0; // 创建DB文件 // 如果不需要创建db文件,使用sqlite3_open即可 ret = sqlite3_open_v2("test.db",&db, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL); if (SQLITE_OK != ret) return false; std::shared_ptr<sqlite3> sp_db(db,[](sqlite3* db){ sqlite3_close(db); }); // 创建表 std::string create = "CREATE TABLE IF NOT EXISTS X_12PHOTO (userid INTEGER PRIMARY KEY, ipaddr" " TEXT,username TEXT,useradd TEXT,userphone INTEGER,age INTEGER, " "time TEXT NOT NULL DEFAULT" " (NOW()));"; // 注意,如果使用了sqlite3_stmt不关闭的话调用sqlite3_close是返回 SQLITE_BUSY 失败的. sqlite3_stmt *stmt = NULL; ret = sqlite3_prepare(db, create.c_str(), create.size(), &stmt, NULL); if(SQLITE_OK != ret) return false; if (sqlite3_step(stmt) != SQLITE_DONE){ sqlite3_finalize(stmt); return false; } sqlite3_finalize(stmt); // 获取数据库匹配的表 static const char* sql = "SELECT name FROM sqlite_master WHERE type=\"table\" AND name REGEXP 'X_[0-9]+PHOTO'"; sqlite3_create_function(db, "regexp", 2, SQLITE_UTF8 | SQLITE_DETERMINISTIC,(void*)sql, &Sqlite3Regexp,NULL,NULL); ret = sqlite3_prepare(db, sql, strlen(sql), &stmt, NULL); if(SQLITE_OK != ret){ return false; } int flag = 0; while(sqlite3_step(stmt) == SQLITE_ROW ){ auto table_sql = (const char*)sqlite3_column_text(stmt,0); std::cout << table_sql << std::endl; } sqlite3_finalize(stmt); sqlite3_create_function(db, "regexp", 2, SQLITE_UTF8 | SQLITE_DETERMINISTIC,0, NULL,NULL,NULL); ::DeleteFile(L"test.db"); return true; } int _tmain(int argc, _TCHAR* argv[]) { assert(TestSqlite3Regexp()); system("pause"); return 0; }
输出:
SELECT name FROM sqlite_master WHERE type="table" AND name REGEXP 'X_[0-9]+PHOTO' X_12PHOTO
参考
1.lang_expr2.create_function
3.sqlite-in-c-and-supporting-regexp
4.icu.c
相关文章推荐
- Oracle中查询使用正则表达式函数REGEXP_LIKE
- SQL数据库查询使用正则表达式查询中文
- 使用CAtlRegExp正则表达式检查浮点数输入
- mysql中如何使用正则表达式查询
- 使用正则表达式获取Sql查询语句各项(表名、字段、条件、排序)
- MySQL中REGEXP正则表达式使用大全
- Lucene使用正则表达式查询
- Oracle 正则表达式函数-REGEXP_REPLACE 使用例子
- 正则表达式初级使用
- mysql中如何使用正则表达式查询
- MySQL知识(十一)——使用正则表达式查询
- MySQL中使用正则表达式查询
- mysql中使用正则表达式查询
- mysql 使用正则表达式查询
- 使用MySQL正则表达式查询
- oracle 使用REGEXP_SUBSTR正则表达式拆分字符串
- Oracle中使用正则表达式过滤查询结果
- Eclipse中的查询支持使用正则表达式
- [ASP]RegExp对象提供简单的正则表达式支持功能使用说明
- MySQL中REGEXP正则表达式使用大全