【问题标题】:Migrate data with INSERT INTO for POSTGRESQL with constraints violated [duplicate]使用 INSERT INTO for POSTGRESQL 迁移数据,违反约束 [重复]
【发布时间】:2015-03-19 09:30:51
【问题描述】:

假设我有两个表,oldstatistics 和 statistics,新表对时间列有不同的约束。

例如,较新的表具有以下约束,而旧表具有违反的数据:

CONSTRAINT check_ts_2013_03 CHECK (statistictime >= '2013-03-01 01:00:00+01'::timestamp with time zone AND statistictime

并且违反的数据假设他们有 statistictime '2013-04-01 00:15:00+01'

我找到了一些使用INSERT OR IGNORE 的 SQLite 解决方案(如果发生约束冲突,行将被跳过,它会继续),但不适用于 POSTGRESQL。

你有什么建议吗?

【问题讨论】:

标签: sql postgresql subquery insert-into


【解决方案1】:

您可以使用 plpgsql 函数和 EXCEPTION 块来执行此操作(请参阅 documentation):

CREATE or REPLACE FUNCTION insert_or_ignore() RETURNS VOID AS $$
DECLARE _value timestamp;

BEGIN
  FOR _value IN SELECT statistictime FROM oldstatistics LOOP   
    BEGIN
      INSERT INTO statistics(statistictime) VALUES (_value);
    EXCEPTION when check_violation THEN
       -- DO NOTHING
    END;
  END LOOP;
END;
$$
LANGUAGE plpgsql;

-- run the function
SELECT insert_or_ignore();

您可能还需要插入其他列,而不仅仅是statistictime。在这种情况下,您必须在 DECLARE 块中声明它们。 你也可以使用 DO 语句来做同样的事情,而不需要先创建一个函数(见documentation:

DO $$
DECLARE _value timestamp;    
BEGIN
      FOR _value IN SELECT statistictime FROM oldstatistics LOOP   
        BEGIN
          INSERT INTO statistics(statistictime) VALUES (_value);
        EXCEPTION when check_violation THEN
           -- DO NOTHING
        END;
      END LOOP;
END$$;

我在这里捕获了“check_violation”异常,但也请查看所有 PostgreSQL 错误代码,以防您想捕获其他类型的错误:error codes

【讨论】:

  • 错误:关系“statistics_2013_03”的新行违反了检查约束“check_ts_2013_03” SQL 状态:23514 确实是 check_violation。问题是它在第一次失败时进入异常分支。但我想继续插入并忽略那些不适合的。
  • 操作,抱歉。我改了答案,再检查一下。
【解决方案2】:

你想对这些数据做什么,想要合并它们?

  • 为了同时使用这两个表,我建议使用视图。
  • 如果您想在不修改数据的情况下将 oldStatisticTime 插入 statisticTime,您可以移除对触发器的约束,无法触发触发器,插入数据然后启用触发器。

【讨论】:

  • 我想通过 select into 将数据从旧表迁移到新表,但由于约束我不能。我没有任何触发器。我应该添加一个吗?
  • 对表的约束由一个表组成,上面写着“那些数据是这个形状”;而触发器(在插入 ei 上)说“所有新数据都将符合这些条件”这就是为什么如果您以相同的方式保持数据,我建议添加触发器而不是约束。特别是如果您的其他选择是绕过您自己的约束
  • 我明白,但不幸的是我不能删除约束。将寻找更多的解决方案。我可能会遍历行并找出数据适合哪个分区。
猜你喜欢
  • 1970-01-01
  • 2011-05-25
  • 1970-01-01
  • 2016-09-28
  • 2017-12-07
  • 2023-03-27
  • 2011-10-17
  • 1970-01-01
相关资源
最近更新 更多