web-dev-qa-db-fra.com

Modifiez le type du champ varchar en entier: "ne peut pas être converti automatiquement en type entier"

J'ai une petite table et un certain champ contient le type "caractère variable". J'essaie de le changer en "Integer" mais cela donne une erreur qui dit que le casting n'est pas possible.

Existe-t-il un moyen de contourner ce problème ou devrais-je simplement créer une autre table et y importer les enregistrements à l'aide d'une requête?.

Le champ ne contient que des valeurs entières.

136
itsols

Il n'y a pas de conversion implicite (automatique) de text ou varchar en integer (vous ne pouvez pas passer un varchar à une fonction qui attend integer ni affecter un varchar champ à un integer), vous devez donc spécifier une conversion explicite à l'aide de ALTER TABLE ... ALTER COLUMN ... TYPE ... USING :

ALTER TABLE the_table ALTER COLUMN col_name TYPE integer USING (col_name::integer);

Notez que vous pouvez avoir des espaces dans vos champs de texte; dans ce cas, utilisez:

ALTER TABLE the_table ALTER COLUMN col_name TYPE integer USING (trim(col_name)::integer);

pour effacer les espaces blancs avant la conversion.

Cela devrait être évident à partir d'un message d'erreur si la commande a été exécutée dans psql, mais il est possible que PgAdmin-III ne vous montre pas l'erreur complète. Voici ce qui se passe si je le teste dans psql sur PostgreSQL 9.2:

=> CREATE TABLE test( x varchar );
CREATE TABLE
=> insert into test(x) values ('14'), (' 42  ');
INSERT 0 2
=> ALTER TABLE test ALTER COLUMN x TYPE integer;
ERROR:  column "x" cannot be cast automatically to type integer
HINT:  Specify a USING expression to perform the conversion. 
=> ALTER TABLE test ALTER COLUMN x TYPE integer USING (trim(x)::integer);
ALTER TABLE        

Merci @muistooshort pour l’ajout du lien USING.

Voir aussi cette question connexe ; il s'agit de Rails migrations, mais la cause sous-jacente est la même et la réponse s'applique.

219
Craig Ringer

this a fonctionné pour moi.

change la colonne varchar en int

change_column :table_name, :column_name, :integer

eu:

PG::DatatypeMismatch: ERROR:  column "column_name" cannot be cast automatically to type integer
HINT:  Specify a USING expression to perform the conversion.

chnged à

change_column :table_name, :column_name, 'integer USING CAST(column_name AS integer)'
65
bibangamba

Vous pouvez le faire comme:

change_column :table_name, :column_name, 'integer USING CAST(column_name AS integer)'

ou essayez ceci:

change_column :table_name, :column_name, :integer, using: 'column_name::integer'

Si vous souhaitez en savoir plus sur ce sujet, lisez cet article: https://kolosek.com/Rails-change-database-column

11
Nesha Zoric

Essayez ceci, cela fonctionnera à coup sûr.

Lors de l'écriture de Rails migrations pour convertir une colonne de chaîne en un entier, vous diriez généralement:

change_column :table_name, :column_name, :integer

Cependant, PostgreSQL va se plaindre:

PG::DatatypeMismatch: ERROR:  column "column_name" cannot be cast automatically to type integer
HINT:  Specify a USING expression to perform the conversion.

Le "conseil" vous dit en gros que vous devez confirmer que vous voulez que cela se produise et comment les données doivent être converties. Dites-le simplement dans votre migration:

change_column :table_name, :column_name, 'integer USING CAST(column_name AS integer)'

Ce qui précède imitera ce que vous savez des autres adaptateurs de base de données. Si vous avez des données non numériques, les résultats peuvent être inattendus (mais vous convertissez en entier, après tout).

7
Subhash Chandra

J'ai le même problème. J'ai alors réalisé que j'avais une valeur de chaîne par défaut pour la colonne que j'essayais de modifier. En supprimant la valeur par défaut, l'erreur disparaissait :)

Si vous avez accidentellement ou non mélangé des entiers avec des données texte, vous devez d'abord exécuter la commande update ci-dessous (sinon, alter table échouera):

UPDATE the_table SET col_name = replace(col_name, 'some_string', '');
1
webrama.pl

Si vous travaillez dans un environnement de développement (ou dans un environnement de production, il peut s'agir de sauvegarder vos données), effacez d'abord les données du champ Base de données ou définissez la valeur sur 0.

UPDATE table_mame SET field_name= 0;

Après cela, exécutez la requête ci-dessous, puis exécutez la requête avec succès, puis exécutez le script de migration.

ALTER TABLE table_mame ALTER COLUMN field_name TYPE numeric(10,0) USING field_name::numeric;

Je pense que cela vous aidera.

0
Sandip Rajput