2015-07-10 104 views
1

我有两个表,我将数据从一个表插入到其他表中。批处理插入的Postgres sql异常处理

insert into a (id1, value1) 
select id, value from b 

id1是唯一的,当我在表b中有重复的id。如何在不停止执行的情况下捕获PostgreSQL中每一行的异常。

+0

是表b中id与给定id不同的值吗? –

+0

是的。值不同 – user2728024

+0

EXCEPTION是什么意思?您可以使用相同的ID插入不同的值。如果您只需要一个值,则需要指定一个条件。 –

回答

2

如果你不能做到为@a_horse_with_no_name建议并避免出现异常,那么PL/PgSQL过程将循环查询并执行一个BEGIN ... EXCEPTION ...块即可。

这是大规模效率低于用WHERE子句和(如果需要)连接过滤问题行,因此如果可能的话应该避免使用它。

有必要的主要时间是,如果通过验证代码抛出异常,您无法运行以生成where子句的布尔值。不幸的是,大多数PostgreSQL的数据类型输入函数没有“测试”模式,在这种模式下,你可以得到一个NULL结果或错误标志用于无效输入,所以这通常是日期/时间解析等情况。

你想要做的事,如:

DO 
LANGUAGE plpgsql 
$$ 
DECLARE 
    r record; 
BEGIN 
    FOR r IN SELECT a, b FROM mytable 
    LOOP 
    BEGIN 
     INSERT INTO newtable (x, y) 
     VALUES (r.a, r.b); 
    EXCEPTION 
     WHEN check_violation THEN 
     RAISE NOTICE 'Skipped row %', r.a; 
    END; 
    END LOOP; 
END; 
$$; 

有关详细信息,请参阅PL/pgSQL的手册。

请注意,这对每个循环迭代都会执行一个子事务,并且每次迭代都需要执行器状态设置,所以它的执行速度比使用INSERT INTO ... SELECT ... WHERE ...时要慢。

+0

解决了这个问题。谢谢。 – user2728024

+0

但它在第一个异常中断,并且不继续循环。 – user2728024

+0

我的不好。当我评论提高命令时工作。谢谢 – user2728024

2

只是不插入那些会导致错误:

insert into a (id1, value1) 
select id, value 
from b 
where not exists (select 1 
        from a 
        where a.id1 = b.id); 

或者只选择那些独特的,如果是空的:

insert into a (id1, value1) 
select distinct on (id) id, value 
from b 
order by id;