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

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. 孙鑫MFC学习笔记1.Windows应用程序运行机理

    1.MSG结构 hwnd:窗口句柄 message:消息类型 wParam & lParam:消息的附加信息(比如键值) time:消息被投递的时间 tip:typedef的作用是从变量类型区 ...

  2. Eclipse设置风格

    如果觉得Eclipse的颜色太刺眼,可以修改背景与字体颜色,方法如下: (1)到http://eclipsecolorthemes.org/下载主题文件,可以选择xml文件或者epf文件: (2)Ec ...

  3. Delphi Mac App 名称支持国际化多语显示

    作用:在 OSX 图标下方显示 App 中文繁体或简体的名称(系统自动选取) 适用:XE7, XE8 for OSX 操作: 创建一个新工程. 在工程目录下创建二个文件夹(zh_??.lproj)文件 ...

  4. [小北De编程手记] : Lesson 03 玩转 xUnit.Net 之 Fixture(上)

    在使用xUnit.Net Framework构建单元测试或自动化测试项目的时候,无论是针对一些比较耗费资源的对象亦或是为了支持Test case预设数据的能力,我们都需要有一些初始化或是清理相关的动作 ...

  5. GJM:用C#实现网络爬虫(一) [转载]

    网络爬虫在信息检索与处理中有很大的作用,是收集网络信息的重要工具. 接下来就介绍一下爬虫的简单实现. 爬虫的工作流程如下 爬虫自指定的URL地址开始下载网络资源,直到该地址和所有子地址的指定资源都下载 ...

  6. tomcat jdk servlet websocket版本对应关系

    最近在考虑公司主要基础三方库版本统一和升级的问题,特看了下tomcat jdk servlet websocket版本的对应关系,如下:

  7. Several ports (8080, 8009) required by Tomcat v6.0 Server at localhost are already in use.

    遇到这个问题似然重启是个办法,但是真心好累.. 1.在dos下,输入  netstat   -ano|findstr  8080 //说明:查看占用8080端口的进程 显示占用端口的进程 2.在任务管 ...

  8. java:JDBC详解

    JDBC全称为:Java DataBase Connectivity(java数据库连接). SUN公司为了简化.统一对数据库的操作,定义了一套Java操作数据库的规范,称之为JDBC.     简单 ...

  9. 使用 FocusPoint.js 实现图片的响应式裁剪

    通常网站的布局都不是单一的.例如图像在电脑.平板和智能手机上可能显示的形状是不同的.特别是如果你使用的是全屏图像,在你必须使用相同的图像文件的情况下,你的主题可能会被截断或完全缺失,或者看起来很尴尬. ...

  10. Maven发布工程到公共库

    1.发布工程 新建一个 Maven build 选择要发布的工程