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.