2015-03-19 71 views
1

假设我有两个表,oldstatistics和统计,新表在时间列不同的约束。用INSERT INTO迁移数据,以便与约束PostgreSQL的侵犯

例如,新表具有以下contraint和旧表中有违反数据:

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

违反假设他们有statistictime“2013年4月1日00及数据:15:00+ 01'

我发现了一些解决方案,SQLite与INSERT OR IGNORE(如果违反约束发生的行将被跳过,它会继续),但不是为POSTGRESQL。

你有什么建议吗?

+0

以及可能的[有没有办法设置一个选项,即使存在错误也会导致PostgreSQL脚本继续?](http:// stackoverflow。 com/q/14908451/1288184):) – 2015-03-19 09:58:10

+0

@SimoKivistö在你的链接问题中指定的答案是使用psql,但这不是我的情况,因为我在python中使用psycopg2模块。 – 2015-03-19 10:01:56

+0

@valentin_nasta您可以使用'DO'在普通SQL中运行PL/pgSQL:http://www.postgresql.org/docs/9.4/static/sql-do.html或创建一个存储函数。 – 2015-03-19 10:03:31

回答

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

+0

错误:关系“statistics_2013_03”的新行违反检​​查约束“check_ts_2013_03” SQL状态:23514 确实是check_violation。问题在于它在EXCEPTION分支上第一次失败。 但我想继续插入和忽略,那些不适合的。 – 2015-03-19 10:18:38

+0

行动,对不起。我改变了我的答案,再次检查。 – 2015-03-19 11:13:50

0

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

  • 对于使用这两个表,我建议使用视图。
  • 如果要插入oldStatisticTime到statisticTime无需修改数据时,可以删除约束至触发,无法触发,插入数据,然后启用触发器。
+0

我想迁移数据,从旧表到新一个支持行选择进入,但我不能因为约束。 我没有任何触发器。 我应该添加一个吗? – 2015-03-19 09:50:54

+0

对表格的约束由一个表格表示'这些数据是这种形状';同时触发器(插入ei)表示'所有新数据都将符合这些条件' 这就是为什么我建议添加一个触发器而不是一个约束条件,如果您保持数据相同的方式。特别是如果你的其他选择是绕过你自己的约束 – jvDx 2015-03-19 10:31:29

+0

我明白,但不幸的是,我不允许删除约束。将寻找更多的解决方案。我可能会遍历行并找出数据适合哪个分区。 – 2015-03-19 10:50:32