Como alterar o tipo de dados da coluna de caractere para numérico no PostgreSQL 8.4

136

Estou usando a seguinte consulta:

ALTER TABLE presales ALTER COLUMN code TYPE numeric(10,0); 

para alterar o tipo de dados de uma coluna de character(20)para, numeric(10,0)mas estou recebendo o erro:

a coluna "código" não pode ser convertida para digitar numérico

user728630
fonte

Respostas:

240

Você pode tentar usar USING:

A USINGcláusula opcional especifica como calcular o novo valor da coluna do antigo; se omitido, a conversão padrão é igual a uma conversão de atribuição do tipo de dados antigo para o novo. Uma USINGcláusula deve ser fornecida se não houver uma conversão implícita ou de atribuição do tipo antigo para o novo.

Portanto, isso pode funcionar (dependendo dos seus dados):

alter table presales alter column code type numeric(10,0) using code::numeric;
-- Or if you prefer standard casting...
alter table presales alter column code type numeric(10,0) using cast(code as numeric);

Isso falhará se você tiver algo codeque não possa ser convertido em numérico; se USING falhar, você deverá limpar manualmente os dados não numéricos antes de alterar o tipo de coluna.

mu é muito curto
fonte
esta coluna é usada como uma chave estrangeira em outra tabela, acho que terei que alterar o tipo de dados disso também?
precisa saber é o seguinte
2
@ user728630: você precisará soltar o FK, alterar as duas colunas e adicionar o FK novamente. Você tem um banco de dados de teste para brincar e um backup do banco de dados de produção, certo?
mu é muito curto
Eu apaguei a restrição de chave estrangeira, alterei o tipo de dados, mas depois disso não foi possível adicionar o FK. Obter o seguinte erro ERRO: a inserção ou atualização na tabela "faturas" viola a restrição de chave estrangeira "invoice_presale_fk" DETALHE: Chave (venda, cpf_cnpj) = (4,05943560000101) não está presente na tabela "pré-vendas".
user728630
2
@funwhilelost Esse é o tipo de elenco . Os documentos ALTER TABLE vinculados abrangem o que você pode usar com USING.
mu é muito curto
3
@muistooshort Eu vejo pelos documentos que na verdade é uma expressão. Isso faz mais sentido. O tipo de elenco me pegou desprevenido. Acabei com #TYPE varchar(255) USING (substring(formertextcolumn from 1 for 255))
funwhilelost 14/03
7

Se sua VARCHARcoluna contiver cadeias vazias (que não são iguais NULLàs do PostgreSQL, como você deve se lembrar), será necessário usar algo na linha a seguir para definir um padrão:

ALTER TABLE presales ALTER COLUMN code TYPE NUMERIC(10,0)
            USING COALESCE(NULLIF(code, '')::NUMERIC, 0);

(encontrado com a ajuda desta resposta )

Patru
fonte