Changer le type de champ varchar en entier: "ne peut pas être lancé automatiquement pour taper entier"
j'ai une petite table et un certain champ contient le type " variant de caractère ". J'essaie de le changer en " entier " mais il donne une erreur que le moulage n'est pas possible.
est-ce qu'il y a un moyen de contourner cela ou devrais-je juste créer une autre table et y apporter les enregistrements en utilisant une requête.
ce champ ne contient que des valeurs entières.
7 réponses
il n'y a pas de coulée implicite (automatique) de text
ou varchar
à integer
(i.e. vous ne pouvez pas passer un varchar
à une fonction en attente integer
ou attribuer un varchar
champ à un integer
), vous devez donc spécifier une coulée explicite en utilisant modifier la TABLE ... ALTER COLUMN ... TYPE. .. En utilisant :
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 rayer l'espace blanc avant conversion.
ce nuage a été é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 toute l'erreur. 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 d'avoir ajouté le lien USING
.
Voir aussi cette question connexe ; il s'agit de migrations de Rails, mais la cause sous-jacente est la même et la réponse s'applique.
ce a travaillé pour moi.
changer la colonne varchar en int
change_column :table_name, :column_name, :integer
a obtenu:
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)'
essayez ça,ça va marcher.
quand vous écrivez des migrations de Rails pour convertir une colonne de chaîne en un entier, vous dites habituellement:
change_column :table_name, :column_name, :integer
cependant, PostgreSQL se plaindra:
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 essentiellement que vous devez confirmer que vous voulez que cela se produise, et comment les données doivent être converties. Il suffit de le dire dans votre migration:
change_column :table_name, :column_name, 'integer USING CAST(column_name AS integer)'
ci-dessus est imiter ce vous connaissez d'autres adaptateurs base de données. Si vous avez des données non numériques, les résultats peuvent être inattendus (mais vous convertissez à un entier, après tout).
j'ai eu le même problème. Puis j'ai réalisé que j'avais une valeur de chaîne par défaut pour la colonne que j'essayais de modifier. Suppression de la valeur par défaut fait l'erreur disparaître :)
Vous pouvez le faire comme:
change_column :table_name, :column_name, 'integer USING CAST(column_name AS integer)'
ou essayez ce qui suit:
change_column :table_name, :column_name, :integer, using: 'column_name::integer'
si vous êtes intéressé pour en savoir plus sur ce sujet, lire l'article: https://kolosek.com/rails-change-database-column
si vous avez accidentellement ou non mélangé des entiers avec des données de texte, vous devez d'abord exécuter ci-dessous la commande de mise à jour (si pas au-dessus alter table échouera):
UPDATE the_table SET col_name = replace(col_name, 'some_string', '');
si vous travaillez sur un environnement de développement(ou sur un environnement de production) il peut être la sauvegarde de vos données) puis d'abord pour effacer les données à partir du champ DB ou de définir la valeur comme 0.
mise à JOUR table_mame ENSEMBLE nom_champ= 0;
après cela pour exécuter la requête ci-dessous et après avoir exécuté avec succès la requête, vers le schemamigration et ensuite exécuter le script migrate.
ALTER TABLE table_mame ALTER COLUMN field_name TYPE numérique (10,0) en utilisant field_name:: numérique;
je pense que ça vous aidera.