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

Oracle 跟踪序列为多个插入创建的所有值,oracle,stored-procedures,plsql,sequence,dblink,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

在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;  
它接受特定用户在某一天完成的所有订单,并将它们插入新数据库。它调用一个序列以确保订单上没有重复的PKs,并且工作正常

但是,我希望使用相同的过程对另一个表进行第二次插入,该表的order_id作为外键。因此,我需要添加刚刚创建的所有order_id,以及源中匹配的数据:

INSERT INTO  ORDER_COMPLETION(order_id, completion_dt)
SELECT ????, completion_dt                    
FROM ORDER_COMPLETION@SOURCE
如何跟踪刚刚创建的订单号与需要从源数据库中提取其数据的订单号匹配

我考虑过创建一个临时表,但不能在过程中创建这些表


其他信息:我将从正在编写的C#app调用此过程ORDERS@SOURCE和命令,以及ORDERS@SOURCE秩序_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

中的行之间必须存在某种链接ORDERS@SOURCE和命令,以及ORDERS@SOURCE秩序_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

我不确定我是否明白这个问题。如果远程数据库中有一个
ORDERS
表和一个
ORDER\u COMPLETION
表,那么在与这两个表相关的源系统上不会有一些键吗?如果该键是订单ID,为什么要在过程中重新分配该键?是否要维护源系统中的
订单ID

如果您确实想在本地重新分配
订单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;

您还可以使用两个
INSERT
语句执行单个
FOR
循环,而不是两个
FORALL
循环。如果每次都要提取大量数据,您可能希望通过向
批量收集添加一个循环和
限制来从远程系统中提取数据,我不确定我是否遵循了这个问题。如果远程数据库中有一个
ORDERS
表和一个
ORDER\u COMPLETION
表,那么在与这两个表相关的源系统上不会有一些键吗?如果该键是订单ID
,为什么要在过程中重新分配该键?是否要维护源系统中的
订单ID

如果您确实想在本地重新分配
订单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;

您还可以使用两个
INSERT
语句执行单个
FOR
循环,而不是两个
FORALL
循环。如果每次都要提取大量数据,您可能希望通过向
批量收集添加一个循环和
限制
,将数据从远程系统中分块提取出来,谢谢您的帮助。与之相关的键是order_id。由于它是订单的主键,因此有一个触发器不允许插入重复值。这两种DBs都经常使用,因此很有可能出现这种情况。我正在研究在这里使用此信息。@null-我仍然不确定是否遵循。您是否真的有手动编码的触发器试图强制执行主键,而不是将列声明为主键并让Oracle使用索引强制执行?
ORDER\u ID
是本地和远程机器上的
ORDERS
表的主键吗?您的目标是在本地数据库和远程数据库上都存在一个特定的
订单ID
,并引用完全不同的订单吗?随着时间的推移,这似乎会引起很大的混乱。我说有扳机确实犯了一个错误。我一边想着索引一边写触发器。这个问题会发生,但实际上不应该给我们造成太多的问题。@null-这个问题是指本地和远程数据库中不同订单的
ORDER\u ID
问题吗?如果您使用远程系统的
订单ID
,而不是重新分配,则根本不会发生这种情况。这似乎仍然是更明智的方法。不幸的是,这是规范的一部分。我是实习生,需要按照主管的话做。然而,当我开始做这项工作时,我得到了一个错误,
FORALL
不能在远程系统上使用,即使我正在循环使用我的等价物
l\u orders
。有什么想法吗?谢谢你的帮助。与之相关的键是order_id。由于它是订单的主键,因此有一个触发器不允许插入重复值。这两种DBs都经常使用,因此很有可能出现这种情况。我正在研究在这里使用此信息。@null-我仍然不确定是否遵循。您是否真的有手动编码的触发器试图强制执行主键,而不是将列声明为主键并让Oracle使用索引强制执行?
ORDER\u ID
是本地和远程机器上的
ORDERS
表的主键吗?您的目标是在本地数据库和远程数据库上都存在一个特定的
订单ID
,并引用完全不同的订单吗?随着时间的推移,这似乎会引起很大的混乱。我说有扳机确实犯了一个错误。我一边想着索引一边写触发器。这个问题会发生,但实际上不应该给我们造成太多的问题。@null-这个问题是指本地和远程数据库中不同订单的
ORDER\u ID
问题吗?如果您使用远程系统的
订单ID
,而不是重新分配,则根本不会发生这种情况。这似乎仍然是更明智的方法。不幸的是,这是规范的一部分。我是实习生,需要按照主管的话做。然而,当我开始做这件事时,我得到了一个错误,
FORALL