【问题标题】:Change type of varchar field to integer: "cannot be cast automatically to type integer"将 varchar 字段的类型更改为整数:“无法自动转换为整数类型”
【发布时间】:2012-10-21 15:45:15
【问题描述】:

我有一个小表,并且某个字段包含“字符变化”类型。我正在尝试将其更改为“Integer”,但它给出了一个错误,即无法进行强制转换。

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

该字段仅包含整数值。

【问题讨论】:

  • 您尝试了哪些具体的 ALTER TABLE,具体的错误信息是什么?
  • @muistooshort 我尝试使用 phppgadmin 的 alter。选择列并尝试输入新的字段类型。错误是:SQL error: ERROR: column "MID" cannot be cast to type integer
  • 首先是备份表。然后你可以在同一个表中创建另一个整数类型的列(比如 field2)。选择将 field1 的整数值强制转换为 field2 。然后重命名该列。
  • @Igor 但新列位于表格的末尾,对吗?我不能把它放在同一个位置吗?
  • @itsols 关心列位置通常是应用程序设计不完善的标志。您几乎总是希望使用显式命名的列和SELECT 列表,而不是依赖于列序号位置。也就是说,答案中给出的方法将保留列位置。

标签: postgresql casting postgresql-9.1 fieldtype


【解决方案1】:

没有从textvarcharinteger 的隐式(自动)转换(即,您不能将varchar 传递给期望integer 的函数或将varchar 字段分配给@987654330 @ one),因此您必须使用 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        

感谢@muistooshort 添加USING 链接。

另见this related question;这是关于 Rails 迁移的,但根本原因是相同的,答案适用。

如果错误仍然存​​在,那么它可能与列值无关,但此列或列默认值的索引可能会导致类型转换失败。需要在 ALTER COLUMN 之前删除索引并在之后重新创建索引。应适当更改默认值。

【讨论】:

  • 感谢您抽出宝贵时间。但我似乎无法让这个工作。我试过你的 ALTER 行,它给了我一个错误“使用附近的语法错误”
  • 我的声明:ALTER TABLE "tblMenus" ALTER COLUMN "MID" USING (trim("MID")::integer);
  • @itsols 完全是我的错误;我在看到您的评论时更正了它。见修订。它在演示代码中是正确的,只是不是一开始的通用示例。
  • 感谢一百万!这个答案为我节省了很多麻烦和时间。我想知道为什么 phppgadmin 和 pgadmin 都没有这个功能......
  • @itsols 大多数核心团队对 PgAdmin 并不感兴趣,而且很少有人使用它。它有一些恼人的可用性缺陷和功能限制。这只是其中之一。因为很少有专家使用 PgAdmin,所以他们没有动力去解决那些会让他们烦恼的事情。我自己不使用它,因为我发现psql 更快更容易。不久前,我写了一些关于 PgAdmin 在备份和恢复方面的可用性的咆哮:blog.ringerc.id.au/2012/05/…
【解决方案2】:

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)'

【讨论】:

  • 您是否尝试过使用数据进行此练习,您的数据是否完好无损?
  • 只要列是整数就可以
  • 它对我不起作用。我正在使用 ruby​​ 2.2.3 和 rails 4.2.3
  • @ThinhD.Bui - 为我工作,2.3.0,rails 4.2.6
  • 也要小心默认值
【解决方案3】:

你可以这样做:

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

【讨论】:

    【解决方案4】:

    试试这个,肯定会成功的。

    在编写 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。这是不可逆转的。我建议在迁移中使用 up 和 down 以使其可逆。
    • PG::InvalidTextRepresentation: ERROR: invalid input syntax for integer: "" 发生错误
    【解决方案5】:

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

    【讨论】:

    • 此列上的现有索引也可能是一个问题。它们需要在 ALTER 之前删除并在之后重新创建。
    【解决方案6】:

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

    change_column :users, :column_name, :boolean, default: nil
    change_column :users, :column_name, :integer, using: 'column_name::integer', default: 0, null: false
    

    【讨论】:

      【解决方案7】:

      如果您在开发环境中工作(或在生产环境中工作。它可能是备份您的数据)然后首先从 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;
      

      我想它会对你有所帮助。

      【讨论】:

        【解决方案8】:

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

        UPDATE the_table SET col_name = replace(col_name, 'some_string', '');
        

        【讨论】:

        • 如果您想去除不需要的字符和空格,最好使用regexp_replace(col_name, '[^0-9.]','','g') 之类的东西。不过,如果您想保留 NaNInf10E42 科学记数法,则需要更复杂的东西。
        猜你喜欢
        • 2021-01-26
        • 1970-01-01
        • 2020-01-13
        • 2020-08-11
        • 2019-02-26
        • 2023-03-28
        • 2012-12-20
        • 1970-01-01
        相关资源
        最近更新 更多