как создать оператор ALTER TABLE, который изменяет таблицу Groups, чтобы имя группы в каждой строке было уникальным

#sql #oracle

#sql #Oracle

Вопрос:

Мой код

 ALTER TABLE groups
MODIFY group_name UNIQUE;
  

Но я получаю сообщение об ошибке и не запускается
, вот сообщение об ошибке :

Ошибка, начинающаяся со строки: 1 в command —
ALTER TABLE GROUPS
ИЗМЕНИТЬ имя_группы УНИКАЛЬНЫЙ
отчет об ошибке —
ORA-02299: не удается проверить (CS270103EX.SYS_C00287085) — найдены дубликаты ключей
02299. 00000 — «не удается проверить (%s.%s) — найдены дубликаты ключей»
* Причина: ограничение проверки alter tableсбой, потому что таблица имеет повторяющиеся значения ключей.
* Действие: очевидно

Комментарии:

1. Вам нужно будет либо сначала удалить неуникальные group_names, а затем добавить ограничение unique (или добавить WITH NOCHECK условие, чтобы применить ваше условие только к будущим данным, а не к текущим данным).

2. *Action: Obvious Немного юмора от авторов сообщений об ошибках. Но это забавно, потому что это правда: вы получаете ошибку, потому что ваша таблица имеет повторяющиеся значения в GROUP_NAME, поэтому, чтобы исправить это, вам нужно удалить дубликаты.

Ответ №1:

Как указывали другие в комментариях, проблема в том, что в настоящее время у вас есть дубликаты, которые мешают вам вносить изменения.

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

 BEGIN
    FOR i
        IN (SELECT GROUP_ID,
                      group_name
                   || ' '
                   || ROW_NUMBER () OVER (PARTITION BY group_name ORDER BY GROUP_ID)    AS new_name
              FROM groups
             WHERE group_name IN (  SELECT group_name
                                      FROM groups
                                  GROUP BY group_name
                                    HAVING COUNT (*) > 1))
    LOOP
        UPDATE groups
           SET group_name = i.new_name
         WHERE GROUP_ID = i.GROUP_ID;
    END LOOP;
END;
  

Ответ №2:

Вы можете создать ограничение в DEFERRABLE NOVALIDATE состоянии and .

Давайте смоделируем ваш случай с помощью этого примера данных

 create table groups as
select 1 id, 1 group_name from dual union all
select 2 id, 1 group_name from dual;
  

Таблица содержит дубликаты в столбце group_name , но вы можете создать ограничение, и теперь недопустимые данные не могут быть добавлены

 ALTER TABLE groups
MODIFY group_name UNIQUE DEFERRABLE ENABLE NOVALIDATE;
  

Давайте проверим это

 insert into groups (group_name) values (1) ;
-- ORA-00001: unique constraint (schema.SYS_C0011643) violated
  

Теперь у вас есть все время, чтобы очистить старые дубликаты

 delete from groups where id = 2;
commit;
  

И, наконец, вы изменяете ограничение на VALIDATE состояние, которое означает, что вся таблица чистая.

 alter table groups modify constraint SYS_C0011643 enable validate;
  

Обратите внимание, что это предпочтительный подход, если у вас очень изменчивая таблица, в которую во время сжатия любой может вставлять новые записи.

Если вы один в базе данных, просто удалите дубликаты и добавьте ограничение.