Come cambiare il tipo di dati della colonna da carattere a numerico in PostgreSQL 8.4


136

Sto usando la seguente query:

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

per cambiare il tipo di dati di una colonna da character(20)a numeric(10,0)ma sto ottenendo l'errore:

la colonna "codice" non può essere trasmessa per digitare un numero

Risposte:


241

Puoi provare a usare USING:

La USINGclausola opzionale specifica come calcolare il nuovo valore di colonna dal vecchio; se omesso, la conversione predefinita è la stessa di un cast di assegnazione dal vecchio tipo di dati al nuovo. È USINGnecessario fornire una clausola se non esiste un cast implicito o di assegnazione dal vecchio al nuovo tipo.

Quindi potrebbe funzionare (a seconda dei tuoi dati):

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);

Questo fallirà se hai qualcosa codeche non può essere convertito in numerico; se USING fallisce, dovrai ripulire i dati non numerici manualmente prima di cambiare il tipo di colonna.


questa colonna viene utilizzata come chiave esterna in un'altra tabella, immagino che dovrò cambiare anche il tipo di dati?
— user728630,

2
@ user728630: Dovrai rilasciare l'FK, cambiare entrambe le colonne e quindi aggiungere nuovamente l'FK. Hai un database di test con cui giocare e un backup del database di produzione, giusto?
— mu è troppo corto il

ho eliminato il vincolo di chiave esterna, modificato il tipo di dati ma dopo non sono riuscito ad aggiungere l'FK. Ottenere il seguente errore ERRORE: inserire o aggiornare nella tabella "fatture" viola il vincolo di chiave esterna "invoice_presale_fk" DETTAGLIO: Chiave (vendita, cpf_cnpj) = (4.05943560000101) non è presente nella tabella "prevendita".
— user728630

2
@funwhilelost Questo è un cast di tipo . I documenti ALTER TABLE collegati descrivono ciò che è possibile utilizzare con USING.
— mu è troppo corto il

3
@muistooshort Vedo dai documenti che in realtà è un'espressione. Questo ha più senso. Il cast del tipo mi ha preso alla sprovvista. Ho finito conTYPE varchar(255) USING (substring(formertextcolumn from 1 for 255))
— funwhilelost il

7

Se la tua VARCHARcolonna contiene stringhe vuote (che non sono le stesse NULLdi PostgreSQL come potresti ricordare) dovrai impostare qualcosa nella riga seguente per impostare un valore predefinito:

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

(trovato con l'aiuto di questa risposta )

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.