Массовый сбор дважды по одной и той же вложенной таблице

Есть ли способ, которым после второго массового сбора данных не будет переопределен первый массовый сбор. Я не хочу повторяться в цикле.

    DECLARE
       TYPE abc IS RECORD (p_id part.p_id%TYPE);

       TYPE abc_nt
       IS
          TABLE OF abc
             INDEX BY BINARY_INTEGER;

       v_abc_nt      abc_nt;
    BEGIN
       SELECT   p_id
         BULK   COLLECT
         INTO   v_abc_nt
         FROM   part
        WHERE   p_id IN ('E1', 'E2');

       SELECT   p_id
         BULK   COLLECT
         INTO   v_abc_nt
         FROM   part
        WHERE   p_id IN ('E3', 'E4');

       FOR i IN v_abc_nt.FIRST .. v_abc_nt.LAST
       LOOP
          DBMS_OUTPUT.put_line (
             'p_id is ' || v_abc_nt (i).p_id
          );
       END LOOP;
    END;

ВЫВОД:

  • p_id is E3
  • p_id is E4

Примечание. E1 и E2 присутствуют в таблице деталей.


person Gaurav Soni    schedule 14.11.2012    source источник


Ответы (2)


Вы не можете просто добавить данные в коллекцию, нет.

Однако вы можете сделать BULK COLLECT в отдельную коллекцию, а затем объединить коллекции, предполагая, что вам действительно нужна/нужна вложенная таблица, а не ассоциативный массив...

DECLARE
   TYPE abc IS RECORD (p_id part.p_id%TYPE);

   TYPE abc_nt
   IS
      TABLE OF abc;

   v_abc_nt       abc_nt;
   v_abc_nt2      abc_nt;
BEGIN
   SELECT   p_id
     BULK   COLLECT
     INTO   v_abc_nt
     FROM   part
    WHERE   p_id IN ('E1', 'E2');

   SELECT   p_id
     BULK   COLLECT
     INTO   v_abc_nt2
     FROM   part
    WHERE   p_id IN ('E3', 'E4');

   v_abc_nt := v_abc_nt MULTISET UNION v_abc_nt2;

   FOR i IN v_abc_nt.FIRST .. v_abc_nt.LAST
   LOOP
      DBMS_OUTPUT.put_line (
         'p_id is ' || v_abc_nt (i).p_id
      );
   END LOOP;
END;

Если вы действительно хотите использовать ассоциативный массив, вам нужно будет написать некоторый код, потому что у Oracle нет возможности автоматически узнать, как переназначить ассоциации одного массива, когда вы объединяете его с другим ассоциативным массивом, который имеет некоторые из тех же ключей. .

person Justin Cave    schedule 14.11.2012
comment
Я запустил ту же процедуру на своей машине, она выдает следующую ошибку: wrong number or types of arguments in call to 'MULTISET_UNION_ALL', пожалуйста, скажите мне, в чем проблема с этим - person Gaurav Soni; 14.11.2012
comment
@GauravSoni - Вы изменили свой код, чтобы использовать вложенную таблицу, а не ассоциативный массив, как я предложил? Если вы все еще пытаетесь использовать ассоциативный массив, вы получите эту ошибку. - person Justin Cave; 14.11.2012
comment
: извините, я вмятина, я изменю это сейчас. Это работает нормально, спасибо, сэр. - person Gaurav Soni; 14.11.2012

Вы можете написать это так

плохой пример:

declare
  type t_numb is record(
    numb number);
  type t_numb_list is table of t_numb;
  v_numb_list t_numb_list;
begin
  with q as
   (select 1 a from dual union select 2 from dual union select 3 from dual)
  select q.a bulk collect into v_numb_list from q;
  with w as
   (select 4 a from dual union select 5 from dual union select 6 from dual)
  select w.a bulk collect into v_numb_list from w;

  for r in 1 .. v_numb_list.count loop
    dbms_output.put_line(v_numb_list(r).numb);
  end loop;
end;

и это работает хорошо:

declare
  type t_numb is record(
    numb number);
  type t_numb_list is table of t_numb;
  v_numb_list t_numb_list := t_numb_list();
  v_numb      t_numb;
begin
  for q in (select 1 a
              from dual
            union
            select 2
              from dual
            union
            select 3
              from dual) loop
    v_numb.numb := q.a;
    v_numb_list.extend;
    v_numb_list(v_numb_list.count) := v_numb;
  end loop;

  for w in (select 4 a
              from dual
            union
            select 5
              from dual
            union
            select 6
              from dual) loop
    v_numb.numb := w.a;
    v_numb_list.extend;
    v_numb_list(v_numb_list.count) := v_numb;
  end loop;

  for r in 1 .. v_numb_list.count loop
    dbms_output.put_line(v_numb_list(r).numb);
  end loop;
end;

person JeSa    schedule 09.11.2017