Oracle 字母数字序列

Posted

技术标签:

【中文标题】Oracle 字母数字序列【英文标题】:Oracle alphanumeric sequence 【发布时间】:2020-10-14 06:43:23 【问题描述】:

我需要在 oracle 中创建一个字母数字序列,但无法弄清楚。已经查过已有的问题,但还没有完全看懂(我的sql知识不是那么好)。

数字 00001 将增加到 00009 然后新系列将从 00000A 开始并增加到 00000Z强>。

那么新系列将从0000A1开始,并增加到0000A9,在这个数字之后,新数字将以0000AA开头,并且上升到 0000AZ

然后是数字 0000B1 上升到 0000B9 然后新系列从 0000BA 开始直到 0000BZ 等等开。

序列也应该有一个前缀,例如CNT00000Z, CNT0000A1

我尝试使用包装函数和不同的 oracle 转换函数(如 substr、mod、to_char 等)来测试不同的设置,但没有成功。

如果您有任何想法,我将不胜感激。

干杯, 亚历山大

【问题讨论】:

将数字序列转换为base 36 可以吗?但这与您所描述的不完全一样,因为Z 之后的数字将是10,而不是A1 在这种情况下,最好写一个“插入前”触发器 还有另一种选择:如果客户端发送它,您可以有一个正常的数字序列并将 id render 作为 base36 和/或 parse 作为 base36作为实体键。这种转换在应用层中最容易执行,但在 SQL 中可能会发生,尽管很难看。 以 1 而不是 A 开头有多重要?在 oracle apex 中有一个名为 compress_int 的函数,可以将整数转换为类似的字符串。但它以 AAAB, AAAC, ... AAA1,AAA2,... 开头。您可以轻松地将前导“A”替换为“0”。该函数的代码可用。如果要求是基于整数生成唯一字符串,这将满足您的要求。如果要求生成一个字符串 exactly 像你的那么它不会。 @WilliamRobertson 恐怕我需要以 10 为底的序列(十进制)。 【参考方案1】:

嗯...如果没有零和 I 和 O,那么它将是自定义 base33 而不是 base34。要做一个“合法”版本,无论您处于什么小数位,数字/字母都以正常方式上升,您可以这样做

SQL> create or replace
  2  function int_to_seq(n in integer ) return varchar2    as
  3     ret       varchar2(30);
  4     quotient  integer;
  5     digit     char(1);
  6     chars varchar2(100) := '123456789ABCDEFGHJKLMNPQRSTUVWXYZ';
  7     len int := length(chars)+1;
  8  begin
  9     quotient := n;
 10     while quotient > 0
 11     loop
 12         ret := substr(chars,mod(quotient,len),1) || ret;
 13         quotient := floor(quotient/len);
 14     end loop ;
 15     return 'CNT'||lpad(ret, 10, '0');
 16  end ;
 17  /

Function created.

SQL>
SQL> select rownum, int_to_seq(rownum) x
  2  from dual
  3  connect by level <= 36
  4  /

    ROWNUM X
---------- ----------------------------------------
         1 CNT0000000001
         2 CNT0000000002
         3 CNT0000000003
         4 CNT0000000004
         5 CNT0000000005
         6 CNT0000000006
         7 CNT0000000007
         8 CNT0000000008
         9 CNT0000000009
        10 CNT000000000A
        11 CNT000000000B
        12 CNT000000000C
        13 CNT000000000D
        14 CNT000000000E
        15 CNT000000000F
        16 CNT000000000G
        17 CNT000000000H
        18 CNT000000000J
        19 CNT000000000K
        20 CNT000000000L
        21 CNT000000000M
        22 CNT000000000N
        23 CNT000000000P
        24 CNT000000000Q
        25 CNT000000000R
        26 CNT000000000S
        27 CNT000000000T
        28 CNT000000000U
        29 CNT000000000V
        30 CNT000000000W
        31 CNT000000000X
        32 CNT000000000Y
        33 CNT000000000Z
        34 CNT0000000011
        35 CNT0000000011
        36 CNT0000000012

36 rows selected.

但如果你真的希望 2nd power 以“A”开头,但最后的地方通过所有 33 个字符,那么你可以这样做

SQL> create or replace
  2  function int_to_seq2(n in integer ) return varchar2    as
  3     ret       varchar2(30);
  4     quotient  integer;
  5     digit     char(1);
  6     chars varchar2(100) := '123456789ABCDEFGHJKLMNPQRSTUVWXYZ';
  7     chars2 varchar2(100) := 'ABCDEFGHJKLMNPQRSTUVWXYZ';
  8     len int := length(chars)+1;
  9  begin
 10     quotient := n;
 11     ret := substr(chars,mod(quotient,len),1) || ret;
 12     quotient := floor(quotient/len);
 13     len := length(chars2)+1;
 14     while quotient > 0
 15     loop
 16         ret := substr(chars2,mod(quotient,len),1) || ret;
 17         quotient := floor(quotient/len);
 18     end loop ;
 19     return 'CNT'||lpad(ret, 10, '0');
 20  end ;
 21  /

Function created.

SQL>
SQL> select rownum, int_to_seq2(rownum) x
  2  from dual
  3  connect by level <= 100
  4  /

    ROWNUM X
---------- ----------------------------------------
         1 CNT0000000001
         2 CNT0000000002
         3 CNT0000000003
         4 CNT0000000004
         5 CNT0000000005
         6 CNT0000000006
         7 CNT0000000007
         8 CNT0000000008
         9 CNT0000000009
        10 CNT000000000A
        11 CNT000000000B
        12 CNT000000000C
        13 CNT000000000D
        14 CNT000000000E
        15 CNT000000000F
        16 CNT000000000G
        17 CNT000000000H
        18 CNT000000000J
        19 CNT000000000K
        20 CNT000000000L
        21 CNT000000000M
        22 CNT000000000N
        23 CNT000000000P
        24 CNT000000000Q
        25 CNT000000000R
        26 CNT000000000S
        27 CNT000000000T
        28 CNT000000000U
        29 CNT000000000V
        30 CNT000000000W
        31 CNT000000000X
        32 CNT000000000Y
        33 CNT000000000Z
        34 CNT00000000A1
        35 CNT00000000A1
        36 CNT00000000A2
        37 CNT00000000A3
        38 CNT00000000A4
        39 CNT00000000A5
        40 CNT00000000A6
        41 CNT00000000A7
        42 CNT00000000A8
        43 CNT00000000A9
        44 CNT00000000AA
        45 CNT00000000AB
        46 CNT00000000AC
        47 CNT00000000AD
        48 CNT00000000AE
        49 CNT00000000AF
        50 CNT00000000AG
        51 CNT00000000AH
        52 CNT00000000AJ
        53 CNT00000000AK
        54 CNT00000000AL
        55 CNT00000000AM
        56 CNT00000000AN
        57 CNT00000000AP
        58 CNT00000000AQ
        59 CNT00000000AR
        60 CNT00000000AS
        61 CNT00000000AT
        62 CNT00000000AU
        63 CNT00000000AV
        64 CNT00000000AW
        65 CNT00000000AX
        66 CNT00000000AY
        67 CNT00000000AZ
        68 CNT00000000B1
        69 CNT00000000B1
        70 CNT00000000B2
        71 CNT00000000B3
        72 CNT00000000B4
        73 CNT00000000B5
        74 CNT00000000B6
        75 CNT00000000B7
        76 CNT00000000B8
        77 CNT00000000B9
        78 CNT00000000BA
        79 CNT00000000BB
        80 CNT00000000BC
        81 CNT00000000BD
        82 CNT00000000BE
        83 CNT00000000BF
        84 CNT00000000BG
        85 CNT00000000BH
        86 CNT00000000BJ
        87 CNT00000000BK
        88 CNT00000000BL
        89 CNT00000000BM
        90 CNT00000000BN
        91 CNT00000000BP
        92 CNT00000000BQ
        93 CNT00000000BR
        94 CNT00000000BS
        95 CNT00000000BT
        96 CNT00000000BU
        97 CNT00000000BV
        98 CNT00000000BW
        99 CNT00000000BX
       100 CNT00000000BY

100 rows selected.

SQL>
SQL>
SQL>

【讨论】:

感谢@Connor McDonald。这正是我所需要的。

以上是关于Oracle 字母数字序列的主要内容,如果未能解决你的问题,请参考以下文章

在 Oracle PL/SQL 中生成字母数字序列

Oracle查询在特殊字符后选择单独的字母+数字和数字

OPENEDGE 字母数字序列函数

oracle 表中如何对按含有字母和数字的编号来进行排序

在Oracle中查找以字母数字开头的字符串

Postgres - 如何创建字母数字序列,如 AAAA0000 等