Отслеживание всех значений, созданных последовательностью для нескольких вставок - PullRequest
1 голос
/ 12 августа 2011

В PL SQL я пишу хранимую процедуру, которая использует ссылку на БД:

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, и он работает хорошо.

Однако я хочу, чтобы эта же процедура выполняла вторую INSERT в другую таблицу, в которой order_id является внешним ключом.Поэтому мне нужно добавить все только что созданный order_id и данные из SOURCE, которые соответствуют:

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

Как я могу отследить, какой только что созданный order_id соответствует тому, чьи данные мне нужныизвлечь из исходной базы данных?

Я пытался создать временную таблицу, но вы не можете создать ее в процедуре.

Другая информация: я буду вызывать эту процедуру из C #приложение, которое я пишу

Ответы [ 2 ]

5 голосов
/ 12 августа 2011

Я не уверен, что следую за вопросом. Если в удаленной базе данных есть таблица 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 голос
/ 12 августа 2011

Должна быть какая-то связь между строками в 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
...