跟踪序列为多个插入创建的所有值

时间:2011-08-12 13:39:51

标签: oracle stored-procedures plsql sequence dblink

在PL SQL中,我正在编写一个使用DB链接的存储过程:

CREATE OR REPLACE PROCEDURE Order_Migration(us_id IN NUMBER, date_id in DATE) 
as 
begin
  INSERT INTO ORDERS(order_id, company_id)
  SELECT ORDER_ID_SEQ.nextval, COMPANY_ID 
  FROM ORDERS@SOURCE
  WHERE USER_ID = us_id  AND DUE_DATE = date_ID;   
end;  

它会在特定日期由特定用户完成所有订单并将其插入新数据库中。它调用一个序列来确保订单上没有重复的PK,并且效果很好。

但是,我希望使用相同的过程对另一个将order_id作为外键的表执行第二次INSERT。所以我需要添加刚刚创建的所有order_id,以及来自SOURCE的匹配的数据:

INSERT INTO  ORDER_COMPLETION(order_id, completion_dt)
SELECT ????, completion_dt                    
FROM ORDER_COMPLETION@SOURCE

如何跟踪刚创建的order_id是否与我需要从源数据库中提取数据的order_id相匹配?

我考虑制作一个临时表,但你不能在程序中创建它们。

其他信息:我将从我正在编写的C#应用​​程序中调用此过程

2 个答案:

答案 0 :(得分:5)

我不确定我是否遵循了这个问题。如果远程数据库中有ORDERS表和ORDER_COMPLETION表,那么源系统上是否存在与这两个表相关的某些键?如果该密钥是ORDER_ID,您为什么要在程序中重新分配该密钥?您不想从源系统维护ORDER_ID吗?

如果您确实想在本地重新分配ORDER_ID,我倾向于认为您想要做类似的事情

CREATE OR REPLACE PROCEDURE order_migration( p_user_id IN orders.user_id%type,
                                             p_due_date IN orders.due_date%type )
AS
  TYPE order_rec IS RECORD( new_order_id  NUMBER,
                            old_order_id  NUMBER,
                            company_id    NUMBER,
                            completion_dt DATE );
  TYPE order_arr IS TABLE OF order_rec;
  l_orders order_arr;
BEGIN
  SELECT order_id_seq.nextval,
         o.order_id,
         o.company_id,
         oc.completion_dt
    BULK COLLECT INTO l_orders
    FROM orders@source o,
         order_completion@source oc
   WHERE o.order_id = oc.order_id
     AND o.user_id  = p_user_id
     AND o.due_date = p_due_date;

  FORALL i IN l_orders.FIRST .. l_orders.LAST
    INSERT INTO orders( order_id, company_id )
      VALUES( l_orders(i).new_order_id, l_orders(i).company_id );

  FORALL i IN l_orders.FIRST .. l_orders.LAST
    INSERT INTO order_completion( order_id, completion_dt )
      VALUES( l_orders(i).new_order_id, l_orders(i).completion_dt );
END;

您还可以使用两个FOR语句而不是两个INSERT循环执行单个FORALL循环。如果您每次都要提取大量数据,则可能需要通过向LIMIT

添加循环和BULK COLLECT来从远程系统中提取数据块。

答案 1 :(得分:1)

ORDERS @ SOURCE和ORDERS以及ORDERS @ SOURCE和ORDER_COMPLETION @ SOURCE之间的行之间必须有一些链接,所以你不能使用连接吗?

类似的东西:

INSERT INTO  ORDER_COMPLETION(order_id, completion_dt)
SELECT o.order_id, ocs.completion_dt                    
FROM ORDER_COMPLETION@SOURCE ocs
JOIN ORDERS o ON o.xxx = ocs.xxx