Вложенный курсор в курсоре - PullRequest
1 голос
/ 13 декабря 2011

У меня есть курсор, который

CURSOR B_CUR IS select DISTINCT big_id from TEMP_TABLE;

Это вернет несколько значений. Ранее он использовался как

FOR b_id IN B_CUR LOOP
    select s.col1, s.col2 INTO var1, var2 from sometable s where s.col3 = b_id.col1;
END LOOP;

Ранее было очевидно, что внутренний запрос на выборку всегда будет возвращать 1 строку. Теперь этот запрос может возвращать несколько строк. Как я могу изменить эту логику?

Я думал о создании вложенного курсора, который будет извлекать массив массива с типом записи (который я объявлю), но я понятия не имею, как здесь будет работать вложенный курсор.

Моя главная забота - эффективность. Так как это будет работать на миллионах записей за исполнение. Не могли бы вы, ребята, предложить лучший подход?

Ответы [ 2 ]

3 голосов
/ 13 декабря 2011

Обычно вы просто объединяете две таблицы.

FOR some_cursor IN (SELECT s.col1,
                           s.col2
                      FROM sometable s
                           JOIN temp_table t ON (s.col3 = t.col1))
LOOP
  <<do something>>
END LOOP

Поскольку вы обеспокоены эффективностью, однако

  • Является ли TEMP_TABLE действительно временной таблицей?Если так, то почему?Крайне редко Oracle требует использования временных таблиц, поэтому я подозреваю, что вы, вероятно, делаете что-то неэффективное для заполнения временной таблицы.
  • Почему у вас есть курсор FOR цикл для обработки данных из TEMP_TABLE?Строковая обработка - самый медленный способ сделать что-либо в PL / SQL, поэтому его, как правило, следует избегать, если вы беспокоитесь об эффективности.С точки зрения производительности, вы хотите максимизировать SQL, чтобы вместо выполнения цикла, который выполнял серию однострочных INSERT или UPDATE операций, вы выполняли одну INSERT или UPDATE, которая изменялавесь набор строк.Если вам действительно нужно обрабатывать данные в блоках, именно здесь вступают в игру коллекции PL / SQL и массовая обработка, но это будет не так эффективно, как прямой SQL.
  • Почему у вас есть DISTINCT вВаш запрос против TEMP_TABLE?Вы действительно ожидаете, что будут дубликаты big_id значений, которые не являются ошибочными?В большинстве случаев люди используют DISTINCT неправильно, чтобы скрыть проблемы, когда данные были неправильно объединены, или когда вы заставляете Oracle выполнять дорогостоящую сортировку на случай, если в будущем будут созданы неправильные данные, когда ограничение будетболее подходящий способ защитить себя.
0 голосов
/ 13 декабря 2011
FOR b_id IN B_CUR LOOP 
  for c_id in  (select s.col1, s.col2 INTO var1, var2 from sometable s where s.col3 = b_id.col1)loop
    ......
  end loop;
END LOOP; 
...