SQL挑战——如何高效生成编码
有这样一个需求:需要根据输入的编码(这个编码值来自于数据库的一个表)生成下一个编码,编码规则如下所示(我们暂且不关心这个逻辑是否合理,只关心如何实现):
1: 最小值为A0000, 最大值为ZZZZZ
2:编码A0000的下一个值为A0001, 编码A9999的下一个值为B0000, 编码AB999的下一个值为AC000,编码AC999的下一个值为AD000,依此规则内推。
3:不用担心输入值为类似A09BC这样的值,应用程序会从表里面取编码的最大值。应用程序也会检查、控制输入参数,不用在数据库的函数(FUNCTION)里面做检查控制。
4:不用担心输入值为ac908这种值(大小写问题),应用程序从表里获取编码的值(不接受用户输入)。所以这个的检查、控制也不用纳入数据库函数考虑范围。
看到同事用ASCII循环判断字符是否为数字,大量的逻辑处理,我觉得并不是如何高效而且有些弄复杂了,写了下面FUN_GEN_NEXT_CODE,用正则表达式获取数字部分,然后根据数字部分进行判断处理。 写完感觉也有点臃肿,因为要花大量的判断处理边界值(A9999 AZ999之类的边界值),但是暂时也没有更好的思路想法。 (ORACLE数据库实现)
CREATE OR REPLACE FUNCTION FUN_GEN_NEXT_CODE(MAX_DEMENSION_NO VARCHAR2)
RETURN VARCHAR2
IS
CodeValue NUMBER(5);
CodeChar VARCHAR(4);
CharValue VARCHAR2(5);
ReturnCode VARCHAR2(5);
BEGIN
IF LENGTH(MAX_DEMENSION_NO) >=6 OR LENGTH(MAX_DEMENSION_NO) < 5 THEN
RETURN '';
END IF;
SELECT REGEXP_SUBSTR(MAX_DEMENSION_NO,'[[:digit:]]+') INTO CodeValue FROM DUAL;
IF LENGTH(CodeValue)= 4 THEN
IF CodeValue= 9999 THEN
IF SUBSTR(MAX_DEMENSION_NO,1,1)='Z' THEN
CharValue :='ZA';
CodeChar := '000';
ELSE
CharValue :=CHR( ASCII(SUBSTR(MAX_DEMENSION_NO,1,1)) +1);
CodeChar := '0000';
END IF;
ELSE
CharValue :=SUBSTR(MAX_DEMENSION_NO,0,1);
CodeChar :=TRIM(TO_CHAR(CodeValue+1,'0000'));
END IF;
ReturnCode :=CharValue || CodeChar;
ELSIF LENGTH(CodeValue)=3 THEN
IF CodeValue= 999 THEN
IF SUBSTR(MAX_DEMENSION_NO,1,2)='ZZ' THEN
ReturnCode :='ZZA' || '00';
ELSE
IF SUBSTR(MAX_DEMENSION_NO,2,1) ='Z' THEN
ReturnCode := CHR( ASCII(SUBSTR(MAX_DEMENSION_NO,1,1)) +1) || '0000';
ELSE
ReturnCode :=SUBSTR(MAX_DEMENSION_NO,1,1) || CHR( ASCII(SUBSTR(MAX_DEMENSION_NO,2,1)) +1) || '000';
END IF;
END IF;
ELSE
ReturnCode :=SUBSTR(MAX_DEMENSION_NO,1,1) || TRIM(TO_CHAR(CodeValue+1,'000'));
END IF;
ELSIF LENGTH(CodeValue)=2 THEN
IF CodeValue= 99 THEN
IF SUBSTR(MAX_DEMENSION_NO,1,3) ='ZZZ' THEN
ReturnCode :='ZZZA0';
ELSE
IF SUBSTR(MAX_DEMENSION_NO,3,1) ='Z' THEN
ReturnCode := SUBSTR(MAX_DEMENSION_NO,1,1) || CHR( ASCII(SUBSTR(MAX_DEMENSION_NO,2,1)) +1) + '000';
ELSE
ReturnCode := SUBSTR(MAX_DEMENSION_NO,1,2) || CHR( ASCII(SUBSTR(MAX_DEMENSION_NO,3,1)) +1) || '00';
END IF;
END IF;
ELSE
ReturnCode :=SUBSTR(MAX_DEMENSION_NO,1,3) + TRIM(TO_CHAR(CodeValue+1,'00'));
END IF;
ELSIF LENGTH(CodeValue)=1 THEN
IF CodeValue= 9 THEN
IF SUBSTR(MAX_DEMENSION_NO, 1,4) ='ZZZZ' THEN
ReturnCode := 'ZZZZA';
ELSE
ReturnCode := SUBSTR(MAX_DEMENSION_NO, 1,3) || CHR( ASCII(SUBSTR(MAX_DEMENSION_NO,4,1)) +1) || '0';
END IF;
ELSE
ReturnCode :=SUBSTR(MAX_DEMENSION_NO,0,4) || TRIM(TO_CHAR(CodeValue+1,'0'));
END IF;
ELSE
IF MAX_DEMENSION_NO='ZZZZZZ' THEN
ReturnCode :='ZZZZZ';
ELSE
ReturnCode :=SUBSTR(MAX_DEMENSION_NO, 1,4) || CHR( ASCII(SUBSTR(MAX_DEMENSION_NO,5,1)) +1);
END IF;
END IF;
RETURN ReturnCode;
EXCEPTION
WHEN OTHERS
THEN
RETURN ('');
END FUN_GEN_NEXT_CODE;
SQL挑战——如何高效生成编码的更多相关文章
- 《万能数据库查询分析器》实现使用SQL语句直接高效地访问文本文件
<万能数据库查询分析器>实现使用SQL语句直接高效地访问文本文件 马根峰 (广东联合电子服务股份有限公司, 广州 510300) 摘要 用SQL语句来直接访问文本文件?是在做梦吗? ...
- SQL Server镜像自动生成脚本
SQL Server镜像自动生成脚本 镜像的搭建非常繁琐,花了一点时间写了这个脚本,方便大家搭建镜像 执行完这个镜像脚本之后,最好在每台机器都绑定一下hosts文件,不然的话,镜像可能会不work 1 ...
- sql 中获取最后生成的标识值 IDENT_CURRENT ,@@IDENTITY ,SCOPE_IDENTITY 的用法和区别
原文:sql 中获取最后生成的标识值 IDENT_CURRENT ,@@IDENTITY ,SCOPE_IDENTITY 的用法和区别 IDENT_CURRENT 返回为任何会话和任何作用域中的指定表 ...
- 运用PowerDesigner的反向工程,可以导入SQL脚本,从而生成物理模型
运用PowerDesigner的反向工程,可以导入SQL脚本,从而生成物理模型.方法/步骤 首先打开PowerDesigner,点击左上角“File”—>"Reverse Engine ...
- SQL Server 2008 转换为 SQL 2005 数据库 脚本生成
Tips: 本文讨论如何把数据库从SQL Server 2008版本降低到2005,因为在本地开发是以SQL Server 2008 Express Edition版本进行的,而主机提供商现在提供的M ...
- 在论坛中出现的比较难的sql问题:24(生成时间段)
原文:在论坛中出现的比较难的sql问题:24(生成时间段) 最近,在论坛中,遇到了不少比较难的sql问题,虽然自己都能解决,但发现过几天后,就记不起来了,也忘记解决的方法了. 所以,觉得有必要记录下来 ...
- 在论坛中出现的比较难的sql问题:15(生成动态删除列语句 分组内多行转为多列)
原文:在论坛中出现的比较难的sql问题:15(生成动态删除列语句 分组内多行转为多列) 所以,觉得有必要记录下来,这样以后再次碰到这类问题,也能从中获取解答的思路. 1.如果去掉这个临时表中合计为0 ...
- 在EF中使用SQL执行简单高效的增删查操作
随着平台数据的积累,对于数据访问的速度要求愈来愈高.优化后台访问性能,将是之后的一个重点任务. 但是,后台在项目开发初期采用的是Abp(Lite DDD)框架,集成EnityFramework.因为之 ...
- 会议更流畅,表情更生动!视频生成编码 VS 国际最新 VVC 标准
阿里云视频云的标准与实现团队与香港城市大学联合开发了基于 AI 生成的人脸视频压缩体系,相比于 VVC 标准,两者质量相当时可以取得 40%-65% 的码率节省,旨在用最前沿的技术,普惠视频通话.视频 ...
随机推荐
- C#遍历Dictionary
C#遍历Dictionary方法 Dictionary<string, int> d = new Dictionary<string, int>(); foreach (Key ...
- Mybatis添加返回主键ID
1.对应xml文件<insert id="insert" parameterType="DetectStandard"useGeneratedKeys=& ...
- Exception loading sessions from persistent storage
严重: Exception loading sessions from persistent storage java.io.EOFException 删除Tomcat里面的work/Catalina ...
- Django 模版语言详解
一.简介 模版是纯文本文件.它可以产生任何基于文本的的格式(HTML,XML,CSV等等). 模版包括在使用时会被值替换掉的 变量,和控制模版逻辑的 标签. 例: {% extends "b ...
- 硬连接与软连接,inode与links
硬连接和软连接,第一感觉就像是window的快捷方式,实则不然 要说硬连接和软连接,那就必须了解inode和block以及分区了 EXT文件系统在创建分区的时候,就划分了两块区域,inode tabl ...
- (1)RGB-D SLAM系列- 工具篇(硬件+关键技术)
/*************************************************************************************************** ...
- Sublime text 3 快捷键的使用
快捷键的便捷使用: ctr+shift+n:打开新的sublime text ctr+shift+w:关闭sublime text ctr+o:打开 某个文件 ctrl+n:新建一个文本 ctrl+w ...
- 百度地图API使用方法详解
最近做了个项目,其中项目中有个需求需要用到百度地图进行导航,通过查阅相关资料参考百度地图api完成了一个例子. API地址:http://developer.baidu.com/map/jsdemo. ...
- SQLServer表内自关联级联删除
今天处理SQLServer级联删除遇到了很蛋疼的事. SQLServer 不支持表内自关联级联删除,而MySql和Oracle却支持. 貌似原因是SQLServer 会产生循环级联,就不给这样弄.所以 ...
- JS魔法堂:jsDeferred源码剖析
一.前言 最近在研究Promises/A+规范及实现,而Promise/A+规范的制定则很大程度地参考了由日本geek cho45发起的jsDeferred项目(<JavaScript框架设计& ...