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;
时间: 2025-01-19 20:00:16

SQL挑战——如何高效生成编码的相关文章

SQL挑战&amp;mdash;&amp;mdash;如何高效生成编码

有这样一个需求:需要根据输入的编码(这个编码值来自于数据库的一个表)生成下一个编码,编码规则如下所示(我们暂且不关心这个逻辑是否合理,只关心如何实现):    1: 最小值为A0000, 最大值为ZZZZZ   2:编码A0000的下一个值为A0001, 编码A9999的下一个值为B0000, 编码AB999的下一个值为AC000,编码AC999的下一个值为AD000,依此规则内推.   3:不用担心输入值为类似A09BC这样的值,应用程序会从表里面取编码的最大值.应用程序也会检查.控制输入参数

PL/SQL Profiler 剖析报告生成html

    使用图形化界面工具实施PL/SQL Profiler 易用直观,但是并不是所有的环境都可以使用图形界面软件连接到数据库.对于只能在命令行下进行剖析又需要直观呈现剖析结果的情形,Oracle为我们提供了脚本来直接生成html文档.本文即是基于这种情形进行演示并加以说明.    有关PL/SQL Profiler的文章可以参考:        使用 DBMS_PROFILER 定位 PL/SQL 瓶颈代码         对比 PL/SQL profiler 剖析结果         使用P

MS SQL 挑战问题

群里面有位网友提出了这样一个SQL挑战问题(原话不是这样,为了说明问题,我略做调整些): 问题说明如下 有一条个销售报表TEST : 商品 金额 A 1400 B 800 C 790 ... ... 现在有这样一个需求(要写一个SQL取出如下数据):先按销售金额倒叙排序,然后从这个报表取出前N条记录,并且这N条记录的销售金额之和是总金额的80%(<= 80%), 80%将作为一个查询条件(有可能是20%,30%).他的想法是用嵌套函数 递归做法记录砍掉一半判断是否达到百分比 如果不足再取后半部分

SQL Server 2000中生成XML的小技巧

本文介绍一个SQL Server 2000中生成XML的小技巧. 以前在介绍SQL2k的时候已经提到了SQL2k对XML的支持,使用for XML语句就可以很容易的把执行的结果转化为一个XML,这样可以在很大程度上提高系统运行效率和开发速度,详细的内容请参见Books Online. 但是在使用ADO(Required ADO 2.6)访问返回的XML的方式和原来的Recordset是有所不同的.如果你还是使用Recordset访问的话,只能得到一个Unicode格式的XML Schema,而无

SQL SERVER2008数据库远程生成脚本问题

问题描述 SQL SERVER2008数据库远程生成脚本问题 我在本机登录远程数据库后生成脚本完成后,远程数据库就登不上了,请问会不会对远程数据库有影响啊?急急急 解决方案 你生成了什么脚本,改变了哪些sql server的设置.如果仅仅是数据库查询,是不会影响登录的.但是你删除了账户甚至停止了sql服务,那就没法登录了. 解决方案二: 如何将数据库sql server2008中的数据库生成脚本输出SQL Server2008 自动生成数据库脚本关于连接SQL Server2008数据库是连接字

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

原文:sql 中获取最后生成的标识值 IDENT_CURRENT ,@@IDENTITY ,SCOPE_IDENTITY 的用法和区别 IDENT_CURRENT 返回为任何会话和任何作用域中的指定表最后生成的标识值. 语法 IDENT_CURRENT('table_name') 参数 table_name 是将要返回其标识值的表的名称.table_name 的数据类型为 varchar,没有默认值. 返回类型 sql_variant 注释 IDENT_CURRENT 类似于 Microsoft

&amp;amp;lt;求教&amp;amp;gt;关于.sql脚本文件如何生成数据库的问题

问题描述 <求教>关于.sql脚本文件如何生成数据库的问题 我使用powerdesigner导出oracle 11g数据库的.sql脚本文件,然后在SQL Plus中执行.sql脚本文件,报出许多错误,包括表名无效,表或视图不存在,指定的索引不存在,在网上找到一些类似的问题,都没能解决,请问有大神知道该如何解决么? 解决方案 我没有用过PowerDesigner生成的脚本.不过一般来说,你从系统生成的脚本,前面有若干DROP的,都是防御性的,是怕你现在生成的库中有相同名称的对象,所以预先帮你把

SQL Server 重新组织生成索引

原文:SQL Server 重新组织生成索引 标签:SQL SERVER/MSSQL SERVER/数据库/DBA/索引/统计信息 概述   无论何时对基础数据执行插入.更新或删除操作,SQL Server 数据库引擎都会自动维护索引.随着时间的推移,这些修改可能会导致索引中的信息分散在数据库中(含有碎片).当索引包含的页中的逻辑排序(基于键值)与数据文件中的物理排序不匹配时,就存在碎片.碎片非常多的索引可能会降低查询性能,导致应用程序响应缓慢,所以在日常的维护工作当中就需要对索引进行检查对那些

SQL Server2008导出数据生成文件

  1.选中要导出的数据库--右键--tasks(任务)--Generate Script(生成脚本),进入脚本生成界面; 2.点"下一步"--(默认选中需要导出的数据库)勾选复选框(Script all objects in the selected database),下一步 --找到"Script Data"(编写数据脚本),将后面的值改为true,(PS:注意选择数据库版本)下一步-- 选中生成脚本后保存的路径.编码等,下一步 3.Finish(完成),在选