Joao Neto’s Blog

Algumas idéias para um mundo melhor – Blog do João Neto!

Auto Increment Para PostGreSQL

Publicado por João em 21 ' setembro 2008

Auto incremento é uma facilidade muito usada em gerenciadores de bancos de dados, como MySQL. Serve para a cada inserção em uma tabela seja gerado um índice único, numérico crescente, facilitando a indexação das tabelas.

Ex no MySQL 5:

CREATE TABLE teste (
idTeste INT NOT NULL AUTO INCREMENT,
nome VARCHAR(20) NOT NULL
);

Crio alguns INSERTS:

INSERT INTO teste(nome) values(‘PRIMEIRA LINHA’);
INSERT INTO teste(nome) values(‘SEGUNDA LINHA’);
SELECT * FROM teste;

idTeste nome
1 PRIMEIRA LINHA
2 SEGUNDA LINHA

Já no PostGreSQL, essa facilidade é obtida de uma forma um pouco diferente:

Primeiro temos que criar uma sequencia:

CREATE SEQUENCE sq_teste_autoIncrement START WITH 1 NO MINVALUE NO MAXVALUE;

Entao crie a tabela:

CREATE TABLE teste (
idTeste INTEGER NOT NULL DEFAULT nextval(‘sq_teste_autoIncrement’),
nome CHARACTER VARYING(20) NOT NULL
);

Com os INSERTS, o resultado é o mesmo:

INSERT INTO teste(nome) values(‘PRIMEIRA LINHA’);
INSERT INTO teste(nome) values(‘SEGUNDA LINHA’);
SELECT * FROM teste;

idTeste nome
1 PRIMEIRA LINHA
2 SEGUNDA LINHA

Para facilitar esse trabalho, um tipo do PostGreSQL para esse tipo de operação é o tipo SERIAL:

CREATE TABLE teste (
idTeste SERIAL NOT NULL,
nome CHARACTER VARYING(20) NOT NULL
);

Quando se executa essa QUERY, o PostGreSQL faz:
1 – Cria uma sequencia de nome <NomeTabela>_<NomeColuna>_seq
2 – Define que a coluna é do tipo INTEGER e que o valor DEFAULT é nextval(<NomeTabela>_<NomeColuna>_seq)

Eu prefiro criar eu mesmo as sequencias e definir o valor padrão dos campos com a função nextval(), as duas operações não contam diferenças para o SGBD (Até porque no fim fazem a mesma coisa), mas criar passo a passo torna o código mais legível – pelo menos pra mim!

Mas, cuidado!
Tente fazer o seguinte (Isso eles não contam na documentação!) :P

CREATE TABLE teste (
idTeste INTEGER NOT NULL DEFAULT nextval(‘sq_teste_autoIncrement’),
nome CHARACTER VARYING(20) NOT NULL
);

INSERT INTO teste(nome) values(‘PRIMEIRA LINHA’);
INSERT INTO teste(nome) values(‘SEGUNDA LINHA’);
SELECT * FROM teste;

idTeste nome
1 PRIMEIRA LINHA
2 SEGUNDA LINHA

Agora:

SELECT currval(‘sq_teste_autoIncrement’) AS valorAutoIncrement;

valorAutoIncrement
3

Obviamente, ao executar outro INSERT o campo idTeste será preenchido com 3, concorda?

Mas, se executar um INSERT assim:

INSERT INTO teste(idTeste, nome) values(5, ‘QUINTA LINHA’);

idTeste nome
1 PRIMEIRA LINHA
2 SEGUNDA LINHA
5 QUINTA LINHA

SELECT currval(‘sq_teste_autoIncrement’) AS valorAutoIncrement;

valorAutoIncrement
3

O que acontece é que a sequencia só incrementa caso seja necessário um valor DEFAULT para o campo, ou seja, apenas quando o campo não for definido em um INSERT.

Como o valor da SEQUENCE é “3″, no próximo segundo INSERT no PostGreSQL poderá acontecer o seguinte:

INSERT INTO teste(nome) values(‘QUARTA LINHA’);
INSERT INTO teste(nome) values(‘QUINTA LINHA DUPLICADA’);

idTeste nome
1 PRIMEIRA LINHA
2 SEGUNDA LINHA
3 TERCEIRA LINHA
5 QUINTA LINHA
4 QUARTA LINHA
5 QUINTA LINHA DUPLICADA

No MySQL, o valor do AUTO INCREMENT nunca possui um valor menor do que MAX(nomeCampo) + 1 do campo em que está sendo usado, evitando esse problema.

Imagine o erro de “duplicar valor da chave viola a restrição de unicidade” caso idTeste fosse chave primária! Entao cuidado…

Um abraço.

Espero ter ajudado!

2 Respostas para “Auto Increment Para PostGreSQL”

  1. Marcelo disse

    Lo mejor es usar el tipo de datos SERIAL :

    CREATE TABLE teste (
    idTeste SERIAL NOT NULL,
    nome CHARACTER VARYING(20) NOT NULL
    );

    SERIAL Crea una secuencia de forma automática y utiliza el tipo de datos INT como base, autoincrementandose automáticamente en 1.

  2. SR.STORK disse

    Ai valeu pela instrução, mais tem uma outra duvida tenho uma tabela com mais ou menos 22 mil linHa pra inserir no banco de dados postesql, mais ela esta no excel a alguma maneira de tranferir este arquivos e deposi anexalos a minha tabela da banco
    sem ter que usar em todos
    insert into NOME_dA_TABELA VALUES (……….);
    PARA TODOS?

Deixe uma resposta

Preencha os seus dados abaixo ou clique em um ícone para log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Sair / Alterar )

Imagem do Twitter

You are commenting using your Twitter account. Sair / Alterar )

Foto do Facebook

You are commenting using your Facebook account. Sair / Alterar )

Connecting to %s

 
Seguir

Obtenha todo post novo entregue na sua caixa de entrada.