我在user中有个表 table1,现在我要根据条件将table1中的数据插入到user2,user3等用户的table1表中,然后通过
job每小时执行一次该存储过程,但由于表都有主键约束,所以在第二次执行的时候就会违反主键唯一约束。。   1. 插入之前判断是否存在该主键值,如果存在就更新,不存在就添加
   2. 删除之前的表数据,然后再添加
但由于表数据量大,而且表结构不一样 如果用以上两种是否又会影响执行速度
,现在就想请教各位高手给我想个万全之策,不胜感激!!

解决方案 »

  1.   

     能把merge放入到存储过程么,因为我呀把存储过程放入job中定时的执行
      

  2.   


    merge是跟insert,update一样的sql语句,完全可以写入存储过程里的。merge的例子如下
    MERGE INTO user2.table1 t2
            USING (SELECT c1,c2,c3 
                     FROM user1.table1  t1
                    )
            ON (    t1.主键=t2.主键)
            WHEN MATCHED THEN
                UPDATE
                   SET t2.c1 = c1, t2.c2=c2 ,t2.c3=c3
            WHEN NOT MATCHED THEN
                INSERT
                VALUES (c1,c2,c3);
      

  3.   


    在过程中就用10g的关键字么
    merge into user2.table1 a using user.table1 b on(a.主键=b.主键)
    when not matched then insert (a.col....) values(b.col....)
    create or trigger tir_table1 before insert on user.table1 for each row
    declare
    num number;
    begin
    select count(1) into num from user2.table1 a where a.主键=:new.主键;
    if num>0 then
    dbms_output.put_line('此表已有此值');
    else 
    insert into user2.table1 values(:new.主键......);
    end if;
    end;
      

  4.   

    可以考虑在table1中增加一个字段来标识是否已同步,或是一个时间字段,根据该时间来判断
    避免每次同步就要进行全表操作
    同步可以使用merge into
      

  5.   

    merge 完全可以放入存储过程里啊,也能解决你描述的问题,有关键字对应的数据时更新某些字段,没有则做插入,而且适合大数据量操作
      

  6.   

    merge into当然可以放在存储过程中了,MERGE不要认为是什么神奇的东西,它就是ORACLE的DML语法中的其中一个,好处就是你数据进行数据判定情况下进行插入,坏处是它的效率比APPEND肯定是要差一些,适用于OLAP系统中。在这类问题处理上要根据是实际的数据量来解决,如果数据量一般般大,你说先删除,后插入比较慢,那是因为删除很慢,因为删除的时候要把数据转入UNDO表空间,也会产生大量的REDO LOG;其实INSERT还是很快的;那么TRUNCATE掉,再ISNERT /*+append*/就O了,我测试过还是蛮快的,不过缺陷是它不能保证事务一致性,也就是你如果INSERT没有数据,那就回滚不回去了,看你数据重要性了。如果你是超大的数据,我建议你还是不要每次都逐行处理,因为MERGE也几乎算是逐行处理的,之所以用于OLAP系统也是不在乎高并发什么的,可以跑很长时间也没事;对于非常大的数据,我建议你们采用增量数据记录法则,类似ORACLE的dataguard一样,它就是采用增量日志将standby数据进行同步法则,这部分你们不用自己去用ORACLE的什么日志,因为一般用户没有那个权限,你可以自己写日志吧;比如还没有同步的数据有,做的是INSERT操作还是UPDATE还是DELETE等等,记录在一个中间表中,同步后,将同步的数据部分删掉,这个中间表我相信不会有太大的数据吧;我想你就是1分钟同步一次也不会消耗什么性能,你可能会想你同步的过程中可能也有插入数据的部分,不用担心,这些问题都是有解决办法的,最简答的办法就是在这个表上增加一个序列号的字段,当你有没有同步的数据的时候,这个字段可以存储SCN号码或者你自己定义的序列号码,每次同步的时候先记录下最大的那个序列号码,同步完后,将中间表的小于这个序列号码的数据删掉;其次你可以用临时表嘛,将中间表存入临时表中,就按照临时表操作,同步完后,将中间表和临时表相同的数据干掉。
    不仅仅是一个表,就算是N个表在这个中间表也使用,增加一个业务类别标识,类别标识进行配置化管理即可完成,这样才能长久性保证你的转存性能,否则如果你的表内部数据超过几千万的时候,你要是用MERGE看看会有有啥事情发生,呵呵。