gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-04 17:49:43 25 4
gpt4 key购买 nike

我想创建一个这样的字母数字序列:

AAAA0000
AAAA0001
AAAA0002
AAAA0003
.
.
.
AAAA9999
AAAB0000
AAAB0001

等等

我已经创建了这个存储过程来做到这一点,但它太慢了:

CREATE OR REPLACE FUNCTION public.fn_batch_seq()
RETURNS text
LANGUAGE plpgsql
AS
$body$
DECLARE
v_sequence TEXT := '';
v_next_sequence TEXT := '';
v_existing_id BIGINT := 0;
BEGIN

/*
* VARCHAR BATCH SEQUENCE FOR SIMCARDS
*/
SELECT "sequence" FROM batch_sequence WHERE id = 1 INTO v_sequence;
IF v_sequence = '' THEN
RAISE NOTICE 'Error - No existe ningun registro en batch_sequence almacenado';
RETURN -500;
END IF;
SELECT perl_increment(v_sequence) INTO v_next_sequence;

IF v_next_sequence = '' THEN
RAISE NOTICE 'Error - La siguiente secuencia generada devolvio null o vacio';
RETURN -500;
END IF;


UPDATE batch_sequence SET "sequence" = v_next_sequence WHERE id = 1;
RETURN v_next_sequence;

EXCEPTION WHEN OTHERS THEN
/*
* Other errors
*/
RAISE NOTICE 'Error General - Posibles causas: No existe la tabla batch_sequence o no existe ningun registro en la misma';
RETURN -500;

END;
$body$
VOLATILE
COST 100;

这个过程使用一个表来存储序列:

CREATE TABLE batch_sequence
(
id serial NOT NULL,
sequence text DEFAULT 'AAAA0000'::text NOT NULL
);

-- Column id is associated with sequence public.batch_sequence_id_seq

ALTER TABLE batch_sequence
ADD CONSTRAINT batch_sequence_pk
PRIMARY KEY (id);

为了增加序列,我使用了一个 perl 过程:

CREATE OR REPLACE FUNCTION public.perl_increment(text)
RETURNS text
LANGUAGE plperl
AS
$body$
my ($x) = @_;
if (not defined $x) {
return undef;
}
++$x;
$body$
VOLATILE
COST 100;

对于大量数据,它工作起来非常慢,因为它必须在插入每一行之前执行。是否有另一种方法可以使用或不使用 Perl 来做到这一点?

请帮忙。

最佳答案

It works very slow with large amount of data, because it must be executed before inserting every single row. Is there another way to do that with or without Perl?

第一个选项:

创建一个序列并对其进行解码:

CREATE SEQUENCE my_serial START 11110000;

翻译成字母左边的部分:

select nextval(''my_serial'') INTO v_nextSeq ;
select translate(
left( trim(to_char(v_nextSeq,'9999')), 4),
'12345','ABCDE')
||
right( trim(to_char(v_nextSeq,'9999')), 4);

第二个选项:

您可以保留所有序列号然后使用它:

**将used 字段添加到您的模式中,记得在序列上创建索引**:

CREATE TABLE batch_sequence
(
id serial NOT NULL,
sequence text DEFAULT 'AAA'::text NOT NULL,
used boolean default false
);

填充整个表,这里简化为2位:

with s as (
SELECT A.a || B.b as sequence
FROM unnest(string_to_array('A B C',' ')) A
CROSS JOIN unnest(string_to_array('0 1 2 3 4 5 6 7 8 9',' ')) B
)
insert into batch_sequence ( sequence )
select s.sequence
from s;

Check all is done :

select * from batch_sequence

Results :

| id | sequence |  used |
|----|----------|-------|
| 28 | A0 | false |
| 29 | A1 | false |
| 30 | A2 | false |
| 31 | A3 | false |
| 32 | A4 | false |
| 33 | A5 | false |
| 34 | A6 | false |
| 35 | A7 | false |
| 36 | A8 | false |
| 37 | A9 | false |
| 38 | B0 | false |
| 39 | B1 | false |
| 40 | B2 | false |
| 41 | B3 | false |
| 42 | B4 | false |
| 43 | B5 | false |
| 44 | B6 | false |
| 45 | B7 | false |
| 46 | B8 | false |
| 47 | B9 | false |
| 48 | C0 | false |
| 49 | C1 | false |
| 50 | C2 | false |
| 51 | C3 | false |
| 52 | C4 | false |
| 53 | C5 | false |
| 54 | C6 | false |
| 55 | C7 | false |
| 56 | C8 | false |
| 57 | C9 | false |

创建一个函数来获取新的序列号并将其设置为已使用

关于sql - Postgres - 如何创建字母数字序列,如 AAAA0000 等,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46075811/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com