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

nul*_*ull 1 oracle plsql stored-procedures dblink sequence

在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;  
Run Code Online (Sandbox Code Playgroud)

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

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

INSERT INTO  ORDER_COMPLETION(order_id, completion_dt)
SELECT ????, completion_dt                    
FROM ORDER_COMPLETION@SOURCE
Run Code Online (Sandbox Code Playgroud)

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

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

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

Jus*_*ave 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;
Run Code Online (Sandbox Code Playgroud)

您也可以FOR使用两个INSERT语句而不是两个FORALL循环执行单个循环.如果你每次都要提取大量数据,你可能希望通过添加一个循环和一个循环LIMIT来从远程系统中提取数据.BULK COLLECT