Сброс ассоциативного массива в PL / SQL? - PullRequest
9 голосов
/ 13 ноября 2009

Это один из тех вопросов, которые "должны быть лучше". Позвольте мне установить проблему, затем я дам вам взломанное решение, и, возможно, вы можете предложить лучшее решение. Спасибо!

Давайте рассмотрим этот маленький кусочек PL / SQL

DECLARE
 TYPE foo_record IS RECORD (foo%type, bar%type);
 TYPE foo_records IS TABLE OF foo_record INDEX BY PLS_INTEGER;
 arr_foos foo_records;

 CURSOR monkeys is SELECT primates FROM zoo;
 row_monkey monkeys%rowtype;
BEGIN
 FOR row_monkey IN monkeys loop
  /*
    at this point in each iteration I need to have the associative array 
    arr_foos in its original state. if this were java, I'd declare it 
    right here and its scope would be limited to this iteration. However, 
    this is not java, so the scope of the array is effectively global and 
    I can't have one iteration's data meddle with the next.
  */
  null;
 END LOOP;
END;

Это имеет смысл? Мне в основном нужно сбросить его на что-то. Если бы это было число, начинающееся с нуля, я мог бы просто сказать число: = 0; в верхней части каждой итерации и покончим с этим. Но это не число, это тип, который я могу просто сбросить с чистой: = 0.

В любом случае, на мой хак:

DECLARE
 TYPE foo_record IS RECORD (foo%type, bar%type);
 TYPE foo_records IS TABLE OF foo_record INDEX BY PLS_INTEGER;
 arr_foos foo_records;
 arr_foos_reset foo_records;

 CURSOR monkeys is SELECT primates FROM zoo;
 row_monkey monkeys%rowtype;
BEGIN
 FOR row_monkey IN monkeys loop
  arr_foos := arr_foos_reset;
  null;
 END LOOP;
END;

Я подумал, что если мне удастся сохранить член того же типа в исходном состоянии, то я могу просто установить рабочую переменную обратно в любое значение, равное исходному. И, что удивительно, это работает (я думаю.) Но должен быть лучший способ. Кто-нибудь может помочь?

T'anks!

Ответы [ 2 ]

27 голосов
/ 14 ноября 2009

Самый простой способ:

arr_foos.Delete();

Другой способ - объявить переменную внутри цикла FOR. Таким образом, он будет воссоздан для каждого прохода.

Как это:

DECLARE
 TYPE foo_record IS RECORD (foo%type, bar%type);
 TYPE foo_records IS TABLE OF foo_record INDEX BY PLS_INTEGER;     

 CURSOR monkeys is SELECT primates FROM zoo;
 row_monkey monkeys%rowtype;
BEGIN
 FOR row_monkey IN monkeys loop
  DECLARE
    arr_foos foo_records;
  BEGIN
    null;
  END;
 END LOOP;
END;
3 голосов
/ 14 ноября 2009

Собираетесь ли вы читать данные из таблицы зоопарка в коллекцию? Тогда есть лучший способ:

DECLARE
  type foos_ts is table of zoo.foo%type index by pls_integer;
  foos foos_t;
BEGIN
  select foo
  bulk collect into foos
  from zoo;
  ...
END;

Массовый сбор автоматически очищает коллекцию перед извлечением и работает быстрее, чем чтение построчно в цикле. К сожалению, он не работает с записями, поэтому вам потребуется несколько таблиц PL / SQL для каждого поля.

Дополнительную информацию можно найти здесь: Получение результатов запроса в коллекции с помощью предложения BULK COLLECT

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...