Итак, вот ваши исходные данные:
SQL> select * from t23
2 /
ID NAM PARENT_ID
---------- --- ----------
1 abc 0
2 efg 1
3 hij 1
4 klm 2
5 nop 3
SQL>
Эта процедура заполняет коллекцию PL / SQL существующими строками. Он проходит по этим строкам, заполняя ассоциативный массив новым идентификатором, который индексируется исходным идентификатором. (Обратите внимание, что для получения значения последовательности в назначении используется синтаксис 11g, а не традиционный выбор из DUAL). Идентификатор затем привязывается к новому значению, а PARENT_ID обновляется значением, сохраненным в ассоциативном массиве. Наконец, новые строки вставляются в таблицу с использованием синтаксиса FORALL
,
SQL> declare
2 type num_lookup is table of pls_integer
3 index by pls_integer;
4 id_translate num_lookup;
5
6 type t23_nt is table of t23%rowtype;
7 new_rows t23_nt;
8 begin
9 select *
10 bulk collect into new_rows
11 from t23
12 order by id asc;
13
14 for i in new_rows.first()..new_rows.last()
15 loop
16 id_translate(new_rows(i).id) := s23.nextval;
17 new_rows(i).id := s23.currval;
18 if new_rows(i).parent_id != 0
19 then
20 new_rows(i).parent_id := id_translate(new_rows(i).parent_id);
21 end if;
22 end loop;
23
24 forall j in new_rows.first()..new_rows.last()
25 insert into t23 values new_rows(j);
26
27 end;
28 /
PL/SQL procedure successfully completed.
SQL>
И, вот!
SQL> select * from t23;
ID NAM PARENT_ID
---------- --- ----------
1 abc 0
2 efg 1
3 hij 1
4 klm 2
5 nop 3
6 abc 0
7 efg 6
8 hij 6
9 klm 7
10 nop 8
10 rows selected.
SQL>