私は小さなテーブルを持っており、特定のフィールドには「文字が変化する」というタイプが含まれています。「 Integer 」に変更しようとしていますが、キャストできないというエラーが発生します。
これを回避する方法はありますか、または別のテーブルを作成し、クエリを使用してレコードをそこに取り込む必要があります。
フィールドには整数値のみが含まれます。
私は小さなテーブルを持っており、特定のフィールドには「文字が変化する」というタイプが含まれています。「 Integer 」に変更しようとしていますが、キャストできないというエラーが発生します。
これを回避する方法はありますか、または別のテーブルを作成し、クエリを使用してレコードをそこに取り込む必要があります。
フィールドには整数値のみが含まれます。
text
fromまたはvarchar
to への暗黙的 (自動) キャストはありません(つまり、aを期待する関数にinteger
渡したり、フィールドをフィールドに割り当てたりすることはできません)、 ALTER TABLE ... ALTER COLUMN ... TYPEを使用して明示的なキャストを指定する必要があります。 .. 使用:varchar
integer
varchar
integer
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);
変換する前に空白を取り除きます。
これは、コマンドが で実行された場合のエラー メッセージから明らかなはずですが、PgAdmin psql
-III が完全なエラーを表示していない可能性があります。psql
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
リンクを追加してくれてありがとう@muistooshort USING
。
この関連する質問も参照してください。それは Rails の移行に関するものですが、根本的な原因は同じであり、答えが当てはまります。
それでもエラーが発生する場合は、列の値ではなく関連している可能性がありますが、この列または列の既定値のインデックスが型キャストに失敗している可能性があります。ALTER COLUMN の前にインデックスを削除し、後で再作成する必要があります。デフォルト値は適切に変更する必要があります。
これは私のために働いた。
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)'
これを試してみてください、それは確かにうまくいくでしょう。
文字列列を整数に変換する 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)'
上記は、他のデータベース アダプターから知っていることを模倣します。数値以外のデータがある場合、結果は予期しないものになる可能性があります (ただし、結局のところ、整数に変換しています)。
同じ問題がありました。列のデフォルトのリセットを開始しました。
change_column :users, :column_name, :boolean, default: nil
change_column :users, :column_name, :integer, using: 'column_name::integer', default: 0, null: false
誤って整数をテキスト データと混合した場合、または混合しなかった場合は、最初に以下の update コマンドを実行する必要があります (上記以外の場合、alter table は失敗します)。
UPDATE the_table SET col_name = replace(col_name, 'some_string', '');