Вот пример.
Тестовый пример первым; test
таблица содержит исходные данные:
SQL> create table test (col clob);
Table created.
SQL> insert into test
2 select '123456 (LED TV); 234543 (LED light); 654876 (LED monitor);' from dual union all
3 select '665988 (Notebook); 987654 (Mouse); 445577 (Dead Pixel);' from dual;
2 rows created.
SQL>
Target
таблица будет содержать значения, извлеченные из источника:
SQL> create table target (itn number, name varchar2(20));
Table created.
SQL> -- This value shouldn't be inserted as it already exists in the TARGET table:
SQL> insert into target values (234543, 'LED light');
1 row created.
SQL>
Теперь кое-что полезное. Идея состоит в том, чтобы разбить значения столбцов на строки (это то, что делает часть regexp_substr
в иерархическом запросе, а затем отделить значение идентификатора от имени (заключенного в скобки). Значения, существующие в целевой таблице, вставлять не следует. (поэтому запрос должен вставлять 5 строк):
SQL> insert into target (itn, name)
2 with
3 c2r as
4 -- split column to rows, e.g. "123456 (LED TV)" is an example of such a row
5 (select to_char(trim(regexp_substr(col, '[^;]+', 1, column_value))) val
6 from test join table(cast(multiset(select level from dual
7 connect by level <= regexp_count(col, ';')
8 ) as sys.odcinumberlist)) on 1 = 1
9 ),
10 sep as
11 -- separate ITN (invoice tracking nubmer) and NAME
12 (select substr(val, 1, instr(val, ' ') - 1) itn,
13 substr(val, instr(val, ' ') + 1) name
14 from c2r
15 )
16 select s.itn, replace(replace(s.name, '(', ''), ')', '')
17 from sep s
18 -- don't insert values that already exist in the TARGET table
19 where not exists (select null from target t
20 where t.itn = s.itn
21 );
5 rows created.
SQL>
Окончательный результат:
SQL> select * From target;
ITN NAME
---------- --------------------
234543 LED light
123456 LED TV
654876 LED monitor
665988 Notebook
987654 Mouse
445577 Dead Pixel
6 rows selected.
SQL>