Можно ли изменить значение первичного ключа записи в Oracle, если существуют дочерние записи? - PullRequest
2 голосов
/ 21 мая 2010

У меня есть несколько таблиц Oracle, которые представляют отношения родитель-потомок. Они выглядят примерно так:

create table Parent (
    parent_id varchar2(20) not null primary key
);

create table Child (
    child_id number not null primary key,
    parent_id varchar2(20) not null,

    constraint fk_parent_id
        foreign key (parent_id)
        references Parent (parent_id)
);

Это живая база данных, и ее схема была разработана давно, исходя из предположения, что поле parent_id будет статичным и неизменным для данной записи. Теперь правила изменились, и мы действительно хотели бы изменить значение parent_id для некоторых записей.

Например, у меня есть эти записи:

Parent:

parent_id
---------
ABC123


Child:

child_id  parent_id
--------  ---------
1         ABC123
2         ABC123

И я хочу изменить ABC123 в этих записях в обеих таблицах на другое.

Насколько я понимаю, нельзя написать оператор обновления Oracle, который будет обновлять родительскую и дочернюю таблицы одновременно, и, учитывая ограничение FK, я не уверен, как лучше обновить мою базу данных. В настоящее время я отключаю ограничение fk_parent_id, обновляю каждую таблицу независимо, а затем включаю ограничение.

Есть ли лучший, одношаговый способ обновить этот контент?

Ответы [ 3 ]

6 голосов
/ 21 мая 2010

Каскадных обновлений нет.

Вы можете использовать отложенное ограничение .

Или, в рамках транзакции:

  • Скопируйте Parent в новую строку с новым ключом:

    INSERT INTO Parent (ключ, столбцы ...) ВЫБЕРИТЕ newkey, cols ... ОТ Родителя Ключ WHERE = oldkey

  • Назначьте всех детей:

    ОБНОВЛЕНИЕ Ребенок SET parent_id = newkey WHERE parent_id = oldkey

  • Удалите родителя теперь, когда на него никто не ссылается:

    DELETE ОТ Родителя Ключ WHERE = oldkey

См. эту ссылку .

3 голосов
/ 21 мая 2010

Если вы обнаружите, что вам необходимо часто обновлять свой первичный ключ, вам может потребоваться переосмыслить вашу модель и использовать истинный неизменный первичный ключ. Используйте столбец с суррогатным ключом, который не имеет смысла (столбец приращения идентификатора или GUID), и сохраните значение, которое вы хотите обновить, только в родительской таблице (чтобы при необходимости его обновления у вас была только одна строка для изменения) .

2 голосов
/ 21 мая 2010

Tom Kyte предоставил утилиту для реализации функции «каскада обновлений» здесь .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...