私は小さなテーブルを持っていて、特定のフィールドにタイプ "character various"が含まれています。これを "Integer"に変更しようとしていますが、キャストできないというエラーが出ます。
これを回避する方法はありますか?それとも別のテーブルを作成し、クエリを使用してそのテーブルにレコードを取り込む必要があります。
フィールドには整数値のみが含まれています。
text
またはvarchar
からinteger
への暗黙的な(自動)キャストはありません(つまり、varchar
を期待する関数にinteger
を渡すことも、varchar
フィールドをinteger
に割り当てることもできません)。したがって、 ALTERを使用して明示的なキャストを指定する必要がありますTABLE ... ALTER COLUMN ... TYPE ... USING :
ALTER TABLE the_table ALTER COLUMN col_name TYPE integer USING (col_name::integer);
テキストフィールドに空白が含まれている場合があることに注意してください。その場合は、次を使用します。
ALTER TABLE the_table ALTER COLUMN col_name TYPE integer USING (trim(col_name)::integer);
変換する前に空白を削除します。
これは、コマンドがpsql
で実行された場合のエラーメッセージから明らかでしたが、PgAdmin-IIIが完全なエラーを表示していない可能性があります。 PostgreSQL 9.2のpsql
でテストするとどうなりますか。
=> 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
USING
リンクを追加してくれてありがとう@muistooshort.
この関連する質問 も参照してください。 Railsの移行についてですが、根本的な原因は同じであり、答えが当てはまります。
this 私のために働いた。
varcharカラムをintに変更
change_column :table_name, :column_name, :integer
得た:
PG::DatatypeMismatch: ERROR: column "column_name" cannot be cast automatically to type integer
HINT: Specify a USING expression to perform the conversion.
に変わった
change_column :table_name, :column_name, 'integer USING CAST(column_name AS integer)'
あなたはそれをすることができます:
change_column :table_name, :column_name, 'integer USING CAST(column_name AS integer)'
またはこれを試してください:
change_column :table_name, :column_name, :integer, using: 'column_name::integer'
このトピックについてもっと知りたい場合は、この記事を読んでください。 https://kolosek.com/Rails-change-database-column
これを試してください、それは確かに動作します。
文字列カラムを整数に変換するためにRailsマイグレーションを書くとき、あなたは通常言うでしょう:
change_column :table_name, :column_name, :integer
しかし、PostgreSQLは次のように文句を言います。
PG::DatatypeMismatch: ERROR: column "column_name" cannot be cast automatically to type integer
HINT: Specify a USING expression to perform the conversion.
「ヒント」は基本的に、これを実現したいかどうかを確認する必要があること、およびデータをどのように変換する必要があるかを示します。マイグレーションの中でこれを言ってください。
change_column :table_name, :column_name, 'integer USING CAST(column_name AS integer)'
上記は他のデータベースアダプタからあなたが知っていることをまねるでしょう。数値以外のデータがある場合、結果は予期しないものになる可能性があります(ただし、結局、整数に変換しているのです)。
私は同じ問題を抱えています。私が気がついたのは、私が変更しようとしていた列にデフォルトの文字列値があることです。デフォルト値を削除するとエラーは消えました:)
誤って整数をテキストデータと混ぜていないのであれば、最初に下記のupdateコマンドを実行してください(上記の範囲を超えていないと、alter tableは失敗します)。
UPDATE the_table SET col_name = replace(col_name, 'some_string', '');
開発環境で作業している場合(または本番環境ではデータをバックアップする場合があります)、まず最初にDBフィールドからデータを消去するか、値を0に設定します。
UPDATEテーブル名SETフィールド名= 0。
その後、以下のクエリを実行し、クエリを正常に実行した後で、スキーマへ移行し、その後でmigrateスクリプトを実行します。
ALTER TABLE table_mame ALTER COLUMN field_nameタイプnumeric(10,0)USING field_name :: numeric;
助けになると思います。