Подход только для SQL
Из-за ограничений на CURRVAL и NEXTVAL, например, их нельзя использовать с DISTINCT, или в подзапросе, или в UNION и т. Д. (См. документация ) решить проблему с помощью SQL немного сложно.Вот решение, которое оставляет исходные таблицы нетронутыми (протестировано с Oracle 12c и 11g).Шаги:
{1} Создайте таблицу (называемую TEMP_), СОЕДИНЯЯ все 3 таблицы «набора таблиц», пометьте каждую строку в итоговой таблице T1 и T2 соответственно.UNION наборы результатов.
{2} Создайте SEQUENCE.
{3} Создайте таблицу MASTER_, содержащую {a} строк для каждого уникального идентификатора (первый запрос) и {b} строк, чьиидентификаторы встречаются более одного раза, причем столбец NEWID заполняется значениями из последовательности (начиная с 100000 в этом примере).
{4} Создайте 3 новые таблицы сведений, выбрав соответствующие столбцы из MASTER _.
Убирать: сбрасывать TEMP_ и MASTER_
- {1}
-- table TEMP_ contains unaltered data from _both_ table sets ( 2 x 3 tables )
-- multiple ID columns removed
-- short names for the original tables:
-- ud -> user_data, ua -> user_addr, us -> user_sal
--
create table temp_
as
select 'TS1' as table_set
, ud1.user_id, ud1.name, ud1.email_id, ud1.date_
, ua1.address, ua1.pin
, us1.sal, us1.effective_date
from ud1
join ua1 on ud1.user_id = ua1.user_id
join us1 on ud1.user_id = us1.user_id
union
select 'TS2' as table_set
, ud2.user_id, ud2.name, ud2.email_id, ud2.date_
, ua2.address, ua2.pin
, us2.sal, us2.effective_date
from ud2
join ua2 on ud2.user_id = ua2.user_id
join us2 on ud2.user_id = us2.user_id
;
- {2}
create sequence uid_seq start with 100000 increment by 1 ;
- {3a}найти уникальные идентификаторы (.NEXTVAL не требуется)
-- column list should be coded (omitted here for clarity)
create table master_ as
select unique_ids.user_id as newid, unique_ids.*
from (
select table_set
, user_id, name, email_id, date_ -- table ud
, address, pin -- table ua
, sal, effective_date -- table us
, row_number() over ( partition by user_id order by table_set ) id_occurences
from temp_
) unique_ids
where id_occurences = 1 ;
- {3b} найти дубликаты идентификаторов, заменить их последовательностью. NEXTVAL
-- We cannot use UNION on the 2 resultsets {3a} and {3b} when creating the MASTER_ table,
-- due to the fact that we are using .NEXTVAL (for duplicate user_ids).
-- However, this 2-step approach works. (CTAS, and subsequent INSERT ... SELECT)
--
-- column list should be coded (omitted here for clarity)
insert into master_
select uid_seq.nextval as newid, duplicates.*
from (
select table_set
-- , uid_seq.nextval -- throws ORA-02287: sequence number not allowed here
, user_id, name, email_id, date_ -- table ud
, address, pin -- table ua
, sal, effective_date -- table us
, row_number() over ( partition by user_id order by table_set ) id_occurences
from temp_
) duplicates
where id_occurences > 1
;
- {4} заполнить новыйтаблицы "part" с данными из MASTER_
-- ud: "user_data"
create table udnew
as
select newid, name, email_id, date_ from master_ ;
-- ua: "user_add"
create table uanew
as
select newid, address, pin from master_ ;
-- us: "use_sal"
create table usnew
as
select newid, sal, effective_date from master_ ;
Новые таблицы содержат ...
SQL> select * from udnew ;
NEWID NAME EMAIL_ID DATE_
---------- ------ -------------- ---------
1 gaurav gav@gmail.com 21-JAN-18
5 kk kk@gmail.com 26-JUN-18
100000 Arun arun@gmail.com 25-JAN-18
SQL> select * from uanew ;
NEWID ADDRE PIN
---------- ----- ----------
1 GZB 325123
5 HYD 564231
100000 Noida 789546
SQL> select * from usnew ;
NEWID SAL EFFECTIVE
---------- ---------- ---------
1 25000 22-MAY-18
5 45000 25-JUL-18
100000 35000 22-JUN-18
Данные испытаний и более подробную информацию: см. Dbfiddle
Альтернативный подход: использовать SQL и PL / SQL
При использовании PL / SQL мы могли бы сделать следующее: {1} создать копии "второго набора" of таблиц, {2} создать требуемую последовательность, {3} написать и выполнить процедуру, которая ОБНОВЛЯЕТ скопированную таблицу, используя .NEXTVALs, где это необходимо. {4} Создайте 3 новые таблицы, написав и выполнив UNION для каждой из таблиц в "набор таблиц 1 ", объединяя их с соответствующими (скопированными) обновленными таблицами" набора таблиц 2 ".
- {1} создает копии" второго набора "таблиц
create table ud2copy as select * from ud2 ;
create table ua2copy as select * from ua2 ;
create table us2copy as select * from us2 ;
- {2} создать требуемую последовательность
create sequence uid_seq start with 100000 increment by 1 ;
- {3} для ОБНОВЛЕНИЯ скопированных таблиц необходимыми .NEXTVALS
create or replace procedure updateIDs
is
begin
for rec_ in (
select uid_seq.nextval new_id, ud2copy.user_id
from ud1
join ud2copy on ud1.user_id = ud2copy.user_id
where ud1.email_id <> ud2copy.email_id
)
loop
update ud2copy set user_id = rec_.new_id where user_id = rec_.user_id ;
update ua2copy set user_id = rec_.new_id where user_id = rec_.user_id ;
update us2copy set user_id = rec_.new_id where user_id = rec_.user_id ;
end loop;
end ;
/
begin
updateIDs ;
commit ;
end ;
/
-{4} создать 3 новые таблицы
create table udnew as select * from ud1 union select * from ud2copy ;
create table uanew as select * from ua1 union select * from ua2copy ;
create table usnew as select * from us1 union select * from us2copy ;
Результат: новые таблицы содержат ...
SQL> select * from udnew ;
USER_ID NAME EMAIL_ID DATE_
---------- ------ -------------- ---------
1 gaurav gav@gmail.com 21-JAN-18
5 kk kk@gmail.com 26-JUN-18
100000 Arun arun@gmail.com 25-JAN-18
SQL> select * from uanew ;
USER_ID ADDRE PIN
---------- ----- ----------
1 GZB 325123
5 HYD 564231
100000 Noida 789546
SQL> select * from usnew ;
USER_ID SAL EFFECTIVE
---------- ---------- ---------
1 25000 22-MAY-18
5 45000 25-JUL-18
100000 35000 22-JUN-18
Dbfiddle здесь.
Авторы комментариев: здесь нет операций BULK или FORALL ... мы знаем: этот код процедуры не так эффективен, как мог бы.Однако код PL / SQL должен быть «достаточно быстрым», поскольку мы имеем дело только с несколькими тысячами строк (на таблицу).