首页 > 代码库 > 通用固定长度编码格式的字符串查找算法的实现
通用固定长度编码格式的字符串查找算法的实现
通用固定长度编码格式的字符串查找算法的实现
字符串的查找是数据库应用中必不可少的操作,而且每种数据库产品(ORACLE、DB2、SYBASE、MS SQL SERVER、MYSQL等等)也都提供了对应的字符串处理函数,比如DB2的LOCATE函数。
但在实际的工作中,还是会遇到一些特殊情况的处理,这使得直接使用字符串查找函数,得到的结果可能是错误的,比如本文中提到的固定长度编码格式的字符串的查找。值得注意的是,本文提出的算法可以稍加修改即移植到其它关系数据库系统或者前端开发工具中。
在实际数据库应用系统中,会经常遇到有些数据表中的一些字段,实际上是采用了某些固定格式的编码规则,比如在本人工作单位中的OLTP数据库中,有一个出口流水表TB_OUTLISTGW中的ROADCOMB字段、ROADSSTARTSTATION字段、ROADSSTARTSTATION字段中都是经过固定长度编码格式的数据,ROADCOMB记录了在广东省高速公路上行驶的车辆所经过的所有高速公路的组合,采用16进制编码,每两位表示一条高速公路的16进制编码,比如11代表10进制的17,即广惠高速公路。
举个例子来说,要统计哪些流水是经过了广惠高速公路(实际上需求比这复杂得多)。大家都会给出以下的SQL 语句(DB2格式)
SELECT *
FROMDEVELOP.TB_OUTLISTGW
WHERELOCATE(ROADCOMB,’11’)>0
FETCH FIRST 100ROW ONLY
WITH UR;
但实际上,这条语句是有一定问题的,ROADCOMB是每两位的16进制数据代表了一条路段,查找的时候需要每两个字符跟目标路段匹配一次,而不是每个字符+后面的字符跟目标字符串逐次进行匹配,本人采取的是以下的做法,建立了一个固定长度编码格式的字符串匹配通用函数,大家可以用其它关系数据库系统的SQL语法格式来翻译过去,这样就可以在其它数据库系统使用了。以下是笔者用万能数据库查询分析器的中文版本《DB 查询分析器》来创建并调用 这个通用的固定长度编码格式的字符串查找函数的过程。(具体方法详见我的博文《DB 查询分析器 6.03 方便地创建DB2自定义函数》 http://blog.csdn.net/magenfeng/article/details/45694907 )
DROP FUNCTION DEVELOP.F_LOCATE_FIXED
$$
---通用的固定长度编码格式的字符串查找函数
CREATE FUNCTION DEVELOP.F_LOCATE_FIXED(IN V_SRC VARCHAR(4096),IN V_DES VARCHAR(4096))
RETURNS INTEGER
LANGUAGE SQL
DETERMINISTIC
NO EXTERNAL ACTION
CONTAINS SQL
BEGIN ATOMIC
DECLARE v_resultINTEGERDEFAULT 0;
DECLARE str_roadVARCHAR(4096);
DECLARE v_len_srcINTEGER;
DECLARE v_len_desINTEGER;
DECLARE v_pos_srcINTEGER DEFAULT 1;
SET v_len_des=LENGTH(TRIM(V_DES));
SET v_len_src=http://www.mamicode.com/LENGTH(TRIM(V_SRC));
SET v_result=0;
AUTHLOOP:
WHILE v_pos_src+v_len_src<=v_len_des DO
SET str_road=SUBSTR(V_DES,v_pos_src,v_len_src);
IF ( str_road=V_SRC ) THEN
SET v_result=v_pos_src; --函数返回匹配的实际物理位置
SET v_result=v_result/v_len_src+1; --函数返回匹配的逻辑位置,即第几个子串位置;这一条语句如果注释掉,函数将返回匹配的实际物理位置
LEAVE AUTHLOOP;
ELSE
SET v_pos_src=http://www.mamicode.com/v_pos_src+v_len_src;
END IF;
END WHILE;
RETURN v_result;
END
$$
values DEVELOP.F_LOCATE_FIXED(‘11‘,‘4F0A0B0D231154533F01‘)
$$
values DEVELOP.F_LOCATE_FIXED(‘11‘,‘01100110011001100110011001100110‘)
$$
SELECT *
FROMDEVELOP.TB_OUTLISTGW
WHERE DEVELOP. F_LOCATE_FIXED (‘11‘,ROADCOMB)>0
FETCH FIRST 100ROW ONLY
WITH UR;
$$
图1 SQL 语句执行前
图2 SQL 语句执行后(一)
图3 SQL 语句执行后(二) values DEVELOP.F_LOCATE_FIXED(‘11‘,‘4F0A0B0D231154533F01‘)的返回结果
图4 SQL 语句执行后(三) values DEVELOP.F_LOCATE_FIXED(‘11‘,‘01100110011001100110011001100110‘)的返回结果
在字符串‘01100110011001100110011001100110‘中查找子串‘11‘,关系数据库系统正常匹配会返回1;但实际情况字符串是2位一组,按照某种编码规则来编码,这种情况下进行固定2位长度进行匹配则会失败,应该返回0 。values DEVELOP.F_LOCATE_FIXED(‘11‘,‘01100110011001100110011001100110‘)也确实是返回了0。
总结: 如果字据库表中的字符串类型的字段查找中要涉及循环查找的话,就必然会用到函数的设计。给大家一个小问题来思考一下,如果要实现的功能是查找出出口流水表TB_OUTLISTGW中ROADCOMB(经过的高速公路列表)、ROADSSTARTSTATION(入口站列表)、ROADESTARTSTATION(出口站列表)中经过了特定调整公路的特定入口站和特定的高速公路出口站的通行记录,那又该如何实现呢?
每一条通行记录所经过的路段、该路段的入口站、该路段的出口站被依次记录在ROADCOMB(经过的高速公路列表)、ROADSSTARTSTATION(入口站列表,4位16进制编码)、ROADESTARTSTATION(出口站列表,4位16进制编码)这三个字段中。
附录一 “万能数据库查询分析器”的简介
中国本土程序员马根峰(CSDN专访马根峰:海量数据处理与分析大师的中国本土程序员)推出的个人作品----万能数据库查询分析器,中文版本《DB 查询分析器》、英文版本《DB Query Analyzer》。它具有强大的功能、友好的操作界面、良好的操作性、跨越各种数据库平台乃至于EXCEL和文本文件。
你可以通过它 ① 查询ODBC数据源(包括世面上所有的数据库、TXT/CSV文件、EXCEL文件)的数据。② 你可以同时执行多条DML语句乃至存贮过程,结果会以你设定的表格、文本框、文件来返回; ③ 从数据库导出千万条数据时,效率与DBMS没有什么区别;④ 具有强大的 SQL “执行计划”功能,你只要将“工具-à选项”窗口中的选项“SQL执行计划连接自动恢复”设置为“选中”状态,那么即使在“SQL执行计划”期间数据库服务器宕过机,只要在“SQL执行计划”的时刻数据库服务器是处理启动状态,那么“SQL执行计划”都会被执行; ⑤ 6.03版本已经完全兼容任何Microsoft的Windows操作系统系列,包括Windows 10、Windows 8、Windows 7、Vista、Windows XP、Windows 2000等等,可以直接在Windows操作系统上运行,而不需要更改任何操作系统的设置或者配置。
《DB 查询分析器》在中关村在线(http://xiazai.zol.com.cn/detail/27/264455.shtml) 下载量超过11万 次,位居整个数据库类排行榜中前10位。
在《程序员》2007第2期的“新产品&工具点评”部分,编辑“特别推荐”了“万能数据库查询分析器”发布。
本人还撰写了关于“万能数据库查询分析器”有关技术的82篇文章,发布在《电脑编程技巧与维护》、《软件》、《计算机时代》、《电脑编程技巧与维护》、百度文库、CSDN资源、和本人的四大博客上(CSDN博客、新浪博客、QQ空间和搜狐博客上)。
DB查询分析器 6.04 中关村在线下载地址:
http://xiazai.zol.com.cn/detail/27/264455.shtml
DBQuery Analyzer 6.04中关村在线下载地址:
http://xiazai.zol.com.cn/detail/43/420901.shtml
作者简介:
马根峰,硕士,研究方向:数据库应用。
个人开发了万能数据库查询分析器,中文版本《DB 查询分析器》、英文版本《DBQuery Analyzer》。它具有强大的功能、友好的操作界面、良好的操作性、跨越各种数据库平台乃至于EXCEL和文本文件。
个人还开发了彻底删除文件(FileDelete Absolutely),用以将Windows系统上的文件彻底删除,不会被其它软件恢复。
这两个软件均免费使用,在各内几大软件下载网站中关村在线、天空软件站、华军软件园、太平洋电脑、非凡软件站、绿色联盟等均有下载。
作者博客:
CSDN博客:http://blog.csdn.net/magenfeng
新浪博客: http://blog.sina.com.cn/magenfeng
QQ空间: http://user.qzone.qq.com/630414817
附录二 本人撰写的关于“万能数据库查询分析器”的82 篇技术文章
目前以下7篇文章发布几个国内计算机刊物上:
[1] 马根峰· 基于数据仓库的广东省高速公路一张网过渡期通行数据及异常分析系统 · 杭州:《计算机时代》,2015年第7期
[2] 马根峰· DB QueryAnalyzer中断SQL语句的执行 · 杭州:《计算机时代》,2011年第12期
[3] 马根峰· DB查询分析器 批量执行DML语句并返回更详细的信息 · 北京:《电脑编程技巧与维护》,2011年第24期
[4] 马根峰· DBQuery Analyzer中的事务管理在DB2中的应用 · 北京:《电脑编程技巧与维护》,2011年第22期
[5] 马根峰· DB查询分析器中断SQL语句的执行· 天津:《软件》,2011年第6期
[6] 马根峰· 万能数据库查询分析器中的事务管理在Oracle中的应用 · 上海:《微型电脑应用》,2011年第11期
[7] 马根峰 · 新产品&工具点评 特别推荐:“万能数据库查询分析器”发布 · 程序员,2007年2期
以下75篇文章发布在百度文库、CSDN资源、和本人的四大博客上:
《万能数据库查询分析器使用技巧之(一)》直到《万能数据库查询分析器使用技巧之(十六)》共16篇
《The 1st tip ofDB Query Analyze》直到《The 16th skills of DB Query Analyzer》共16篇
《如何在客户端配置ODBC来访问远程DB2 for Windows服务器》
《How to configure ODBC DSN in Client toaccess remote DB2 for Windows》
《如何在服务器上配置ODBC来访问本机DB2 forWindows服务器》
《How to configure ODBC DSN to access localDB2 for Windows》
《软件开发顶尖高手的杀手锏SQL语句》
《Which SQL statement is the trump card tothe senior software developer》
《DB 查询分析器批量执行DML语句并返回更详细的信息》
《用“万能数据库查询分析器”测试SQLite对4大SQL精髓语句的支持》
《用“DB查询分析器”的对象浏览器来展现数据库的数据字典》
《万能数据库查询分析器用户已基本涵盖当前所有数据库系统》
《The DBMS that DB Query Analyzer Users oftenuse cover all kinds of DBMS》
《查询分析器应必须具备的功能-中断查询的执行》
《万能数据库查询分析器的EXE文件加壳技术》
《Exe packer prevent DB Query Analyzer frombeging debugged》
《自己开发的“万能数据库查询分析器”终于有了较大的成果》
《DB Query Analyzer中断SQL语句的执行》
《DB 查询分析器 批量执行DML语句并返回更详细的信息》
《DB Query Analyzer中的事务管理在DB2中的应用》
《DB 查询分析器中断SQL语句的执行》
《万能数据库查询分析器中的事务管理在Oracle中的应用》
《特别推荐:“万能数据库查询分析器”发布》
《软件开发高手须掌握的4大SQL精髓语句(一)》
《软件开发高手须掌握的4大SQL精髓语句(二)》
《软件开发高手须掌握的4大SQL精髓语句(三)》
《软件开发高手须掌握的4大SQL精髓语句(四)》
《软件开发高手须掌握的4大SQL精髓语句(综合篇)》
《巅峰之作----“万能数据库查询分析器”5.01发布》
《万能数据库查询分析器与EXCEL强强联合进行数据分析》
《DB 查询分析器批量执行多条SQL语句并查看各自的执行时间》
《DB查询分析器访问EXCEL时,要在表名前后加上中括弧或双引号》
《The table name must be enclosed in double quotation marks or squarebracket while accessing EXCEL by DB Query Analyzer》
《如何使用ZOL一键安装器下载中关村在线的源安装包》
《How to download the installation package byZOL Downer》
《DB 查询分析器 6.03 ,遨游于任何Windows操作系统之上的最优秀的数据库客户端工具》
《DB Query Analyzer, the mostexcellent Universal database Access tools on any Microsoft Windows OS 》
《DB 查询分析器 6.03 在Windows 8.1上安装与运行演示》
《Demonstration of DB QueryAnalyzer 6.03 Installation and Running on Microsoft Windows 8 》
《DB 查询分析器 6.03 方便地创建DB2自定义函数》
《How to easily create DB2 user function byDB Query Analyzer 6.03 》
《DB 查询分析器 6.04 在 Windows 10 上的安装与运行展示》
《Install and run DB Query Analyzer 6.04 onMicrosoft Windows 10》
《通用固定长度编码格式的字符串查找算法的实现》
《A universal function of searchingfixed-length coded string in a string field》
在字符串‘01100110011001100110011001100110‘中查找子串‘11‘,关系数据库系统正常匹配会返回1;但实际情况字符串是2位一组,按照某种编码规则来编码,这种情况下进行固定2位长度进行匹配则会失败,应该返回0 。values DEVELOP.F_LOCATE_FIXED(‘11‘,‘01100110011001100110011001100110‘)也确实是返回了0。
总结: 如果字据库表中的字符串类型的字段查找中要涉及循环查找的话,就必然会用到函数的设计。给大家一个小问题来思考一下,如果要实现的功能是查找出出口流水表TB_OUTLISTGW中ROADCOMB(经过的高速公路列表)、ROADSSTARTSTATION(入口站列表)、ROADESTARTSTATION(出口站列表)中经过了特定调整公路的特定入口站和特定的高速公路出口站的通行记录,那又该如何实现呢?
每一条通行记录所经过的路段、该路段的入口站、该路段的出口站被依次记录在ROADCOMB(经过的高速公路列表)、ROADSSTARTSTATION(入口站列表,4位16进制编码)、ROADESTARTSTATION(出口站列表,4位16进制编码)这三个字段中。
马根峰本人的微信公众号:
万能数据库查询分析器
马根峰的博客:
CSDN博客:http://blog.csdn.net/magenfeng
新浪博客: http://blog.sina.com.cn/magenfeng
官方网址: http://www.unitedpowersoft.com/
更多精彩文章,技术分享,敬请期待
通用固定长度编码格式的字符串查找算法的实现