Em 10 de outubro de 2011 22:12, Nei Rauni Santos <[email protected]> escreveu:
> Pessoal,
> Atualmente minha chave primária da tabela é um ID sequencial em uma coluna
> do tipo INTEGER.
> Preciso fazer com que os novos registros entrem com um ID não sequencial,
> estou pensando em fazer algo assim:
>
>
> CREATE OR REPLACE FUNCTION inquiry.generate_id( size integer)
>   RETURNS BIGINT AS
> $BODY$
> DECLARE
>   _SIZE ALIAS FOR $1;
>   _CODE BIGINT;
>   _NUMBERS INTEGER[];
> BEGIN
>   FOR i IN 1.._SIZE LOOP
>     IF i = 1 THEN
>     _NUMBERS[ i ] := COALESCE( trunc(random() * (9-0) + 0), 1);
>     ELSE
>     _NUMBERS[ i ] := trunc(random() * (9-0) + 0);
>     END IF;
>
>     SELECT INTO _CODE array_to_string( _NUMBERS, '' );
>   END LOOP;
>   WHILE ( ( SELECT count(*) FROM inquiry.inquiry where id = _CODE ) > 0 )
> LOOP
>    _CODE := inquiry.generate_id( _SIZE );
>   END LOOP;
>
>   RETURN _CODE;
> END;
> $BODY$
>   LANGUAGE plpgsql VOLATILE
>   COST 100;
> chamando a função irá retornar um bigint com 10 posições:
> SELECT inquiry.generate_id( 10 );
> 4624763011
> 3018760860
> 3272802221
> 2685162564
> obs. o número nunca poderá comecar com zero.
>
> Gostaria da opnião de vocẽs e quem sabe sugestões para melhorar essa função.

Nei, existe um problema: concorrência.

Veja, quando você utiliza nextval, setval e currval, eles tem um
comportamento especial, já que nextval, por exemplo, precisa alterar o
valor da sequence imediatamente para todas as transações correntes,
mesmo que você dê um rollback na transação ue o originou, ele
simplesmente ficará inutilizado.

Como você iria controlar concorrência? Por mais que você utilize
random, pode ocorrer de duas transações gerarem o mesmo valor e você
gerar uma violação de restrição na chave ao inserir.

Você precisa mesmo de um ID de 10 posições aleatório? Você não
precisaria talvez de algo como UUID [1]?

[1] http://www.postgresql.org/docs/current/interactive/uuid-ossp.html
-- 
Dickson S. Guedes
mail/xmpp: [email protected] - skype: guediz
http://guedesoft.net - http://www.postgresql.org.br
_______________________________________________
pgbr-geral mailing list
[email protected]
https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral

Responder a