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 字母数字序列的主要内容,如果未能解决你的问题,请参考以下文章