创建字母数字序列

时间:2015-06-10 10:54:49

标签: sql oracle function plsql sequence

我想创建一个生成如下值的序列:

A00000000
A00000001
..
..
..
A99999999
B00000000
B00000001
..
..

应该使用初始字母字符A生成,一旦达到A99999999,它应该更改为B,依此类推。

Oracle中的正常序列不会提供字母数字序列。如何在此模式中生成连续值?

3 个答案:

答案 0 :(得分:5)

您必须创建1个序列和1个转换函数:

CREATE SEQUENCE num_seq
START WITH 6500000000
INCREMENT BY 1
MAXVALUE 9099999999;

FUNCTION next_id(seq_name) RETURN VARCHAR2 IS
  x VARCHAR2(28);
BEGIN
  EXECUTE IMMEDIATE 'SELECT TRIM(TO_CHAR(' || seq_name || '.NextVal)) FROM dual' INTO x;
  RETURN CHR(TO_NUMBER(SUBSTR(x, 1, 2))) || SUBSTR(x, 3);
END;

当使用A00000000调用时,该函数会从Z99999999生成ID到next_id('num_seq')。诀窍是CHR(ascii_code)函数,它返回65-90位的字符,即A-Z。

<强>编辑:
函数更通用 - 您可以将任何序列作为参数传递,您只需在SEQUENCE定义的START WITH和MAXVALUE子句中添加/删除数字,而无需更改函数。

答案 1 :(得分:4)

您可以创建数字序列,但可以动态将前两个字符转换为十六进制值。如果您将序列创建为:

create sequence s42 start with 1000000000 maxvalue 1599999999;

...然后有一个简化的功能,虽然你并不严格需要它:

create function alpha_seq return varchar2 as
begin
  return to_char(trunc(s42.nextval / 100000000), 'FMXX')
    || substr(to_char(s42.currval, 'FM0000000000'), 3);
end;
/

序列值始终为10位数。前两个被拉出并转换为十六进制等值,然后附加其余部分。

作为演示:

select alpha_seq from dual
connect by level < 5;

ALPHA_SEQ
----------
A00000000 
A00000001 
A00000002 
A00000003 

-- skip a load of numbers
alter sequence s42 increment by 99999994;
select alpha_seq from dual;

ALPHA_SEQ
----------
A99999997 

alter sequence s42 increment by 1;

select alpha_seq from dual
connect by level < 5;

ALPHA_SEQ
----------
A99999998 
A99999999 
B00000000 
B00000001 

-- skip a load of numbers
alter sequence s42 increment by 99999996;
select alpha_seq from dual;

ALPHA_SEQ
----------
B99999997 

alter sequence s42 increment by 1;

select alpha_seq from dual
connect by level < 5;

ALPHA_SEQ
----------
B99999998 
B99999999 
C00000000 
C00000001 

序列上的最大值意味着它将达到F99999999,如果再次调用nextval则会出错。我假设第一个数字应该是十六进制的;如果您想要A-Z,那么您可以将序列开始为6500000000并将前两位数转换为带有chr()的字符,而不是将65转换为A等等。

答案 2 :(得分:-3)

function generate_universal_id(pid){
    let BASE_VALUE = 100000000;
    let prefix = ['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'];
    let prefix_index = pid/100000;
    let intvalue = Math.floor( prefix_index );
    prefix = prefix[intvalue];
    BASE_VALUE = BASE_VALUE + pid;
    BASE_VALUE = BASE_VALUE.toString().slice(-5);

    if(pid == 100000 || pid == 200000 || pid == 300000 || pid == 400000 || pid == 500000 || pid == 600000 || pid == 700000 || pid == 800000 || pid == 900000 ){
        BASE_VALUE = BASE_VALUE + 1;
    }
    BASE_VALUE = BASE_VALUE.toString().slice(-5)
    let universal_id = `${prefix}${BASE_VALUE}`
    console.log(universal_id);
}

generate_universal_id(100000)