【问题标题】:Find what row holds a value which cannot be cast to integer查找哪一行包含一个不能转换为整数的值
【发布时间】:2013-12-16 20:34:51
【问题描述】:

我在重排数据表方面进行了一些操作,到目前为止效果很好。
在一个超过 50000 行的表中,我有一个文本列,其中的文本只能是数字。
现在我想将其转换为整数列。
所以:

ALTER TABLE mytable ALTER COLUMN mycolumn TYPE integer;

这会产生错误 42804: *datatype_mismatch*

通过阅读文档,我找到了解决方案:

ALTER TABLE mytable ALTER COLUMN mycolumn TYPE integer USING (TRIM(mycolumn)::integer); 

但我知道数据的平均数字顺序可能不正确,因为这会“掩盖”错误,并且有可能(手动)编辑了列。毕竟,可能只是添加了尾随空格或进行了其他一些小的编辑。

我有数据备份。
我如何找到给定列的哪个确切单元格包含错误以及哪个值不能通过一些适合从 pgadmin 使用的方便查询转换为 int?

如果不是太复杂,请那个查询。

【问题讨论】:

  • this answer 不是为您提供解决方案吗?
  • 有一些提示,但我仍然不知道如何在所描述的需要中使用它们。
  • 在转换为 int 时,我只能得到“整数的输入语法无效”错误。什么样的垃圾会产生 datatype_mismatch 错误?

标签: postgresql


【解决方案1】:

扩展 @dystroy 的答案,这个查询应该准确地找出任何有问题的行的值:

CREATE OR REPLACE FUNCTION convert_to_integer(v_input text)
RETURNS INTEGER AS $$
BEGIN
    BEGIN
        RETURN v_input::INTEGER;
    EXCEPTION WHEN OTHERS THEN
        RAISE EXCEPTION 'Invalid integer value: "%".  Returning NULL.', v_input;
        RETURN NULL;
    END;
END;
$$ LANGUAGE plpgsql;

原答案:

如果以下方法有效:

ALTER TABLE mytable
ALTER COLUMN mycolumn TYPE integer USING (TRIM(mycolumn)::integer);

那么您应该可以运行以下命令来定位垃圾箱:

select mycolumn from mytable
where mycolumn::text <> (TRIM(mycolumn)::integer)::text;

【讨论】:

  • 我切换到原始数据,但找不到该查询的错误(仍然存在)。我还尝试“从 mytable 中选择 mycolumn,其中 NOT mycolumn::integer=index;”知道 int index 和 text mycolumn 应该代表相同的数字。
  • 你真的不知道什么样的垃圾会给你这些错误信息?
  • 我也成功地尝试了 'dystroy' 推荐的 convert_to_integer 函数。这将成功转换所有数据。但干净的方式仍然给我:“错误:列“mycolumn”不能转换为整数**********错误**********错误:列“mycolumn”不能转换键入整数 SQL 状态:42804"。不,我不知道这可能是什么原因以及在哪里引起的。
  • Hold... a) 在一种情况下,您将无法强制转换为整数类型,而在另一种情况下则类型不匹配。您能否仔细检查并确认您发布的 alter table 语句实际运行时没有错误?
  • 此外,@dystroy 的原始 convert_to_integer 将捕获并取消违规行。它旨在始终成功。 (有关将拒绝无效输入的版本,请参阅我的更新答案。)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-21
  • 1970-01-01
  • 1970-01-01
  • 2017-08-12
相关资源
最近更新 更多