Как скопировать данные по измерению, избегая проблем с уникальными именами в Oracle - PullRequest
0 голосов
/ 21 января 2020

База данных: Oracle 18 c

Информация о данных:

У нас есть временное понятие сезонов, и у нас есть набор бизнес-групп в каждый сезон. В моей таблице AGROUP есть столбцы (идентификатор * [автоматически сгенерирован], NAME, SEASON_ID). Имена групп должны быть уникальными в зависимости от сезона. Иными словами, я могу иметь две группы с одинаковым именем ТОЛЬКО , если они находятся в разные времена года.

Задача под рукой:

Мне нужно создать хранимую процедуру, которая с учетом исходного сезона и целевого сезона , можно скопировать все группы из исходного сезона в целевой сезон. Эта часть достаточно проста. Наивное решение:

PROCEDURE COPY_GROUPS(IN_SOURCE_SEASON_ID IN SEASON.ID%TYPE,
                      IN_TARGET_SEASON_ID IN SEASON.ID%TYPE)
AS 

WITH SOURCE AS 
      (SELECT AG.ID AS AG_ID,
              AG.NAME,
              AG.SEASON_ID
       FROM AGROUP AG
       WHERE AG.SEASON_ID = IN_SOURCE_SEASON_ID)

INSERT INTO AGROUP (NAME, SEASON_ID)
SELECT SRC.NAME,
       IN_TARGET_SEASON_ID AS SEASON_ID,
FROM SOURCE SRC;
COMMIT;
END;

Хитрость заключается в том, что существует вероятность того, что в целевом сезоне существует группа, которая уже имеет то же имя, что и группа в исходном сезоне. Без вмешательства это приведет к уникальной ошибке ограничения. В этом случае мы хотим скопировать группу, но переименовать ее в нечто уникальное. Любой способ переименования - это хорошо, но моя первая мысль - просто переименовать с суффиксным номером. Чтобы сделать это, я полагаю, что я бы изменил все вокруг, чтобы открыть через REFCURSOR и l oop, вставляя по одному и перехватывая уникальную ошибку ограничения и отвечая повторной попыткой вставить с суффиксом числа. Я действительно опыт работы с обработкой ошибок маршрутизации, как это в Oracle однако. Я действительно мог бы использовать некоторые указания в правильном направлении.

Спасибо за помощь!

1 Ответ

1 голос
/ 21 января 2020

Я немного поиграл с этим. Я бы сказал, чтобы попытаться сделать условную логику c в выражении case согласно следующему примеру. Вам понадобится лучший способ генерации последовательностей.

/* INSERT INTO AGROUP (id, NAME, SEASON_ID) */
WITH agroup as 
(
select 1 id, 'A' name, 1 season_id from dual union
select 2 id, 'A' name, 2 season_id from dual union
select 3 id, 'B' name, 1 season_id from dual union
select 4 id, 'C' name, 2 season_ud from dual
)
, SOURCE AS 
(SELECT rownum row_num, AG.ID AS AG_ID,
AG.NAME,
AG.SEASON_ID
FROM AGROUP AG
WHERE AG.SEASON_ID = 1 /* source season */
)
SELECT /* sequence generation */ (select max(id) from agroup) + row_num as id
,      case when SRC.NAME in (select name 
                              from agroup 
                              where agroup.season_id = 2 /* target season */ 
                                and agroup.name = src.name
                             )
            then src.name || ' ' || to_char(sysdate, 'DD-MON-YYYY hh24:MI:SS')
            else src.name
       end as name
, 2 /* target season */ AS SEASON_ID
FROM SOURCE SRC
;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...