使用INSERT INTO为POSTGRESQL迁移数据时违反了约束

时间:2015-03-19 09:30:51

标签: sql postgresql subquery insert-into

假设我有两个表,旧统计和统计,较新的表对时间列有不同的约束。

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

  

CONSTRAINT check_ts_2013_03 CHECK(statistictime> ='2013-03-01   01:00:00 + 01'::带时区的时间戳和统计时间< “2013年4月1日   02:00:00 + 02'::带时区的时间戳)

和违反的数据让我们说他们有统计时间'2013-04-01 00:15:00 + 01'

我找到了一些带有INSERT OR IGNORE的SQLite解决方案(如果发生约束违规,将跳过行,它将继续),但不会对POSTGRESQL。

你有什么建议吗?

2 个答案:

答案 0 :(得分:2)

您可以使用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

答案 1 :(得分:0)

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

  • 为了使用这两个表,我建议使用视图。
  • 如果要在不修改数据的情况下将oldStatisticTime插入到statisticTime中,可以将约束移除到触发器,无法触发,插入数据然后启用触发器。
相关问题