186

我有一张小桌子,某个字段包含“字符变化”类型。我正在尝试将其更改为“整数”,但它给出了一个错误,即无法进行转换。

有没有办法解决这个问题,或者我应该创建另一个表并使用查询将记录带入其中。

该字段仅包含整数值。

4

8 回答 8

312

没有从textvarchar到的隐式(自动)强制转换integer(即,您不能将 a 传递varchar给期望的函数integer或将varchar字段分配给一个),因此您必须使用ALTER TABLE ... ALTER COLUMN ... TYPEinteger指定显式强制转换。 .. 使用

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 可能没有向您显示完整的错误。如果我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 之前删除索引并在之后重新创建索引。应适当更改默认值。

于 2012-11-01T03:47:21.260 回答
76

对我有用。

将 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)'
于 2014-07-30T08:35:04.280 回答
22

你可以这样做:

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

于 2018-05-09T08:55:10.077 回答
9

试试这个,它肯定会起作用。

在编写 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)'

以上将模仿您从其他数据库适配器中了解的内容。如果您有非数字数据,结果可能会出乎意料(但毕竟您要转换为整数)。

于 2016-04-15T12:56:46.560 回答
7

我遇到了同样的问题。比我意识到我尝试更改的列有一个默认字符串值。删除默认值使错误消失:)

于 2017-05-17T15:33:49.153 回答
3

我遇到过同样的问题。我开始重置列的默认值。

change_column :users, :column_name, :boolean, default: nil
change_column :users, :column_name, :integer, using: 'column_name::integer', default: 0, null: false
于 2020-06-03T09:01:52.673 回答
2

如果您正在开发环境(或生产环境。它可能是备份您的数据),那么首先从 DB 字段中清除数据或将值设置为 0。

UPDATE table_mame SET field_name= 0;

之后运行以下查询并成功运行查询后,到 schemamigration,然后运行 ​​migrate 脚本。

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

我想它会对你有所帮助。

于 2015-06-29T13:10:25.493 回答
1

如果您不小心将整数与文本数据混合在一起,您应该首先执行以下更新命令(如果不是高于 alter table 将失败):

UPDATE the_table SET col_name = replace(col_name, 'some_string', '');
于 2013-04-08T07:40:09.300 回答