Вложенный курсор в курсор

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

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 строку. Теперь этот запрос может возвращать несколько строк. Как я могу изменить эту логику?

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

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


person x.509    schedule 12.12.2011    source источник


Ответы (1)


Обычно вы просто присоединяетесь к двум таблицам.

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.
  • Почему в вашем запросе вместо TEMP_TABLE стоит DISTINCT? Вы действительно ожидаете, что будут повторяющиеся значения big_id, которые не являются ошибочными? В большинстве случаев люди используют DISTINCT неправильно либо для сокрытия проблем, связанных с неправильным объединением данных, либо для того, чтобы заставить Oracle выполнять дорогостоящую сортировку на случай, если в будущем будут созданы неправильные данные, когда ограничение будет более подходящим. способ защитить себя.
person Justin Cave    schedule 12.12.2011
comment
* Temp_table не является временной таблицей. Я переименовал исходную таблицу только для совместного использования. 2: Перед внутренним циклом реализуется ряд бизнес-логики. это что-то outer_loop ... logic ... inner loop. Так что Joins здесь не сработает. 3: Отдельное ключевое слово принесет отдельный big_id, поскольку pk для temp_table — это что-то другое, и может быть несколько big_id для каждого pk в таблице. - person x.509; 13.12.2011