有这样一个需求:需要根据输入的编码(这个编码值来自于数据库的一个表)生成下一个编码,编码规则如下所示(我们暂且不关心这个逻辑是否合理,只关心如何实现):

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挑战——如何高效生成编码的更多相关文章

  1. 《万能数据库查询分析器》实现使用SQL语句直接高效地访问文本文件

    <万能数据库查询分析器>实现使用SQL语句直接高效地访问文本文件 马根峰 (广东联合电子服务股份有限公司, 广州 510300) 摘要    用SQL语句来直接访问文本文件?是在做梦吗? ...

  2. SQL Server镜像自动生成脚本

    SQL Server镜像自动生成脚本 镜像的搭建非常繁琐,花了一点时间写了这个脚本,方便大家搭建镜像 执行完这个镜像脚本之后,最好在每台机器都绑定一下hosts文件,不然的话,镜像可能会不work 1 ...

  3. sql 中获取最后生成的标识值 IDENT_CURRENT ,@@IDENTITY ,SCOPE_IDENTITY 的用法和区别

    原文:sql 中获取最后生成的标识值 IDENT_CURRENT ,@@IDENTITY ,SCOPE_IDENTITY 的用法和区别 IDENT_CURRENT 返回为任何会话和任何作用域中的指定表 ...

  4. 运用PowerDesigner的反向工程,可以导入SQL脚本,从而生成物理模型

    运用PowerDesigner的反向工程,可以导入SQL脚本,从而生成物理模型.方法/步骤 首先打开PowerDesigner,点击左上角“File”—>"Reverse Engine ...

  5. SQL Server 2008 转换为 SQL 2005 数据库 脚本生成

    Tips: 本文讨论如何把数据库从SQL Server 2008版本降低到2005,因为在本地开发是以SQL Server 2008 Express Edition版本进行的,而主机提供商现在提供的M ...

  6. 在论坛中出现的比较难的sql问题:24(生成时间段)

    原文:在论坛中出现的比较难的sql问题:24(生成时间段) 最近,在论坛中,遇到了不少比较难的sql问题,虽然自己都能解决,但发现过几天后,就记不起来了,也忘记解决的方法了. 所以,觉得有必要记录下来 ...

  7. 在论坛中出现的比较难的sql问题:15(生成动态删除列语句 分组内多行转为多列)

    原文:在论坛中出现的比较难的sql问题:15(生成动态删除列语句 分组内多行转为多列) 所以,觉得有必要记录下来,这样以后再次碰到这类问题,也能从中获取解答的思路. 1.如果去掉这个临时表中合计为0 ...

  8. 在EF中使用SQL执行简单高效的增删查操作

    随着平台数据的积累,对于数据访问的速度要求愈来愈高.优化后台访问性能,将是之后的一个重点任务. 但是,后台在项目开发初期采用的是Abp(Lite DDD)框架,集成EnityFramework.因为之 ...

  9. 会议更流畅,表情更生动!视频生成编码 VS 国际最新 VVC 标准

    阿里云视频云的标准与实现团队与香港城市大学联合开发了基于 AI 生成的人脸视频压缩体系,相比于 VVC 标准,两者质量相当时可以取得 40%-65% 的码率节省,旨在用最前沿的技术,普惠视频通话.视频 ...

随机推荐

  1. 关于SilverLight

    目前工作中用到SilverLight,有必要对其作一定的了解.

  2. 关于 Servlet 和 Web

       文中也只是对Servlet和Web作简单的了解,有个初步的认识,深入的内容有待于进一步去研究. T. T _ . _ Servlet     Servlet(Server Applet),全称J ...

  3. html5学习笔记4--API Range对象(一)

    Range对象基本用法 效果图如下(在谷歌浏览器下的展示)

  4. serialize()序列化

  5. WITH RECURSIVE and MySQL

    WITH RECURSIVE and MySQL If you have been using certain DBMSs, or reading recent versions of the SQL ...

  6. BeforeProperties/AfterProperties in Event Receivers

    Sharepoint List List BeforeProperties AfterProperties properties.ListItem ItemAdding No Value No Val ...

  7. mysql经纬度查询并且计算2KM范围内附近用户的sql查询性能优化实例教程

    之前很傻很天真地以为无非就是逐个计算距离,然后比较出来就行了,然后当碰到访问用户很多,而且数据库中经纬度信息很多的时候,计算量的迅速增长,能让服务器完全傻逼掉,还是老前辈的经验比我们丰富,给了我很大的 ...

  8. Nodejs与ES6系列4:ES6中的类

    ES6中的类 4.1.class基本语法 在之前的javascript语法中是不存在class这样的概念,如果要通过构造函数生成一个新对象代码 function Shape(width,height) ...

  9. Shepherd – 在应用程序中轻松实现引导功能

    Shepherd 是一个指导用户使用应用程序的 JavaScript 库.它使用 Tether——另一个开源库,实现所有的步骤.Tether 确保你的步骤不会溢出屏幕或被剪裁.你可以很容易地指导用户使 ...

  10. Chance – 功能强大的 JavaScript 随机数生成类库

    Chance 是一个基于 JavaScript 的随机数工具类.可以生成随机数字,名称,地址,域名,邮箱,时间等等,几乎网站中使用的任何形式的内容都能够生成.这个随机数工具可以帮助减少单调的测试数据编 ...