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
