Quando percebemos, após a tabela ser criada, que foi cometido um erro ou que os requisitos da aplicação mudaram, é possível remover a tabela e criá-la novamente. Porém, esta opção não é conveniente quando existem dados na tabela, ou se a tabela for referenciada por outros objetos do banco de dados (por exemplo, uma restrição de chave estrangeira); por isso, o PostgreSQL fornece uma família de comandos para realizar modificações em tabelas existentes. Note que esta operação é conceitualmente distinta da alteração dos dados contidos na tabela, aqui o interesse está em mudar a definição, ou estrutura, da tabela.
É possível:
Adicionar colunas
Remover colunas
Adicionar restrições
Remover restrições
Mudar o valor padrão de colunas
Mudar o tipo de dados de colunas
Mudar o nome de colunas
Mudar o nome de tabelas
Todas estas ações são realizadas utilizando o comando ALTER TABLE, cuja página de referência contém mais detalhes do que os fornecidos aqui.
Para adicionar uma coluna é usado um comando como:
ALTER TABLE produtos ADD COLUMN descricao text;
Inicialmente a nova coluna é preenchida com o valor padrão
especificado, ou nulo se a cláusula DEFAULT não
for especificada.
Adicionar uma coluna com um valor padrão constante não exige que
cada linha da tabela seja atualizada quando a instrução
ALTER TABLE for executada.
Em vez disso, o valor padrão será retornado na próxima vez que a
linha for acessada e aplicado quando a tabela for reescrita,
tornando o comando ALTER TABLE muito rápido,
mesmo em tabelas grandes.
Se o valor padrão for volátil (por exemplo,
clock_timestamp()) cada linha precisará ser
atualizada com o valor calculado no momento em que o comando
ALTER TABLE foi executado.
Para evitar uma operação de atualização potencialmente demorada,
especialmente se for pretendido preencher a coluna principalmente
com valores diferentes do padrão, pode ser preferível adicionar a
coluna sem nenhum valor padrão, inserir os valores corretos usando
UPDATE e, em seguida, adicionar o valor padrão
desejado, conforme descrito abaixo.
Também podem ser definidas, ao mesmo tempo, restrições para a coluna utilizando a sintaxe habitual:
ALTER TABLE produtos ADD COLUMN descricao text CHECK (descricao <> '');
Na verdade, todas as opções que se aplicam à descrição da coluna no
comando CREATE TABLE também podem ser utilizadas
aqui.
Entretanto, tenha em mente que o valor padrão deve satisfazer
às restrições especificadas, ou o ADD COLUMN
não será bem-sucedido.
Como alternativa, as restrições podem ser adicionadas posteriormente
(veja abaixo), após a nova coluna ter sido preenchida corretamente.
Para remover uma coluna é usado um comando como:
ALTER TABLE produtos DROP COLUMN descricao;
Os dados presentes na coluna desaparecem. As restrições de tabela
que envolvem a coluna também são removidas. Entretanto, se a coluna
for referenciada por uma restrição de chave estrangeira de outra
tabela, o PostgreSQL não irá remover esta
restrição silenciosamente. Pode ser autorizada a remoção de tudo que
depende da coluna adicionando CASCADE:
ALTER TABLE produtos DROP COLUMN descricao CASCADE;
Veja a Seção 5.15 para obter uma descrição geral do mecanismo por trás dessa operação.
Para adicionar uma restrição é utilizada a sintaxe de restrição de tabela. Por exemplo:
ALTER TABLE produtos ADD CHECK (nome <> ''); ALTER TABLE produtos ADD CONSTRAINT algum_nome UNIQUE (num_produto); ALTER TABLE produtos ADD FOREIGN KEY (produto_id_grupo) REFERENCES produtos_grupos;
Para adicionar uma restrição de não-nulo, que normalmente não é escrita como uma restrição de tabela, está disponível esta sintaxe especial:
ALTER TABLE produtos ALTER COLUMN num_produto SET NOT NULL;
Se a coluna já tiver uma restrição de não-nulo, este comando não fará nada e ficará em silêncio.
A restrição será verificada imediatamente, portanto os dados da tabela devem satisfazer à restrição para ela poder ser adicionada.
Para remover uma restrição é necessário conhecer seu nome.
Se foi atribuído um nome à restrição será fácil, caso contrário
será necessário descobrir o nome gerado que sistema atribuiu à
restrição. O comando
\d nome_da_tabela do
psql pode ser útil nesta situação; outras
interfaces também podem fornecer uma forma de inspecionar os
detalhes das tabelas. O comando utilizado para remover restrição é:
ALTER TABLE produtos DROP CONSTRAINT algum_nome;
Assim como ao remover uma coluna, será necessário adicionar
CASCADE se for desejado excluir uma restrição
da qual outro objeto depende.
Um exemplo é quando uma restrição de chave estrangeira depende
de uma restrição de chave primária ou de unicidade existente
na(s) coluna(s) referenciada(s).
Existe uma sintaxe simplificada para remover uma restrição de não-nulo:
ALTER TABLE produtos ALTER COLUMN num_produto DROP NOT NULL;
Isso espelha a sintaxe SET NOT NULL para
adicionar uma restrição de não-nulo.
Se a coluna não tiver uma restrição de não-nulo, este comando não
fará nada e ficará em silêncio.
(Lembre-se de que uma coluna pode ter no máximo uma restrição de
não-nulo, portanto, nunca haverá ambiguidade sobre qual restrição
este comando irá atuar.)
Para definir um novo valor padrão é usado um comando como:
ALTER TABLE produtos ALTER COLUMN preco SET DEFAULT 7.77;
Note que este comando não afeta nenhuma coluna
existente na tabela, apenas muda o valor padrão para os próximos
comandos INSERT.
Para remover o valor padrão da coluna é usado um comando como:
ALTER TABLE produtos ALTER COLUMN preco DROP DEFAULT;
Isto é de fato idêntico a definir o valor padrão como nulo. Como consequência, não é errado remover um valor padrão que não foi definido, porque o valor padrão é implicitamente o valor nulo.
Para converter a coluna para um tipo de dados diferente é usado um comando como:
ALTER TABLE produtos ALTER COLUMN preco TYPE numeric(10,2);
Este comando somente será bem-sucedido se todas as entradas existentes
na coluna puderem ser convertidas para o novo tipo de dados através de
conversão implícita. Se for necessária uma conversão mais complexa,
poderá ser adicionada a cláusula USING
especificando como calcular os novos valores a partir dos antigos.
O PostgreSQL tenta converter o valor padrão da coluna (se houver) para o novo tipo de dados, assim como todas as restrições que envolvem a coluna. Mas estas conversões podem falhar, ou podem produzir resultados surpreendentes. Geralmente é melhor remover todas as restrições da coluna antes de alterar o seu tipo de dados e, depois, adicionar novamente estas restrições modificadas de forma apropriada.
Para mudar o nome de uma coluna é usado um comando como:
ALTER TABLE produtos RENAME COLUMN num_produto TO cod_produto;
Para mudar o nome de uma tabela é usado um comando como:
ALTER TABLE produtos RENAME TO itens;