2015-10-04 10 views
0

Я пытаюсь написать процедуру PL/SQL, которая будет искать существующий первичный ключ «поставщик_ид» из таблицы поставщика и заменять его новым. Первичный ключ «поставщик_ид» также является внешним ключом для нескольких других таблиц. Поэтому мне нужно также обновить расположение внешних ключей. Вот процедура я написал для решения этой проблемы:Замена первичного ключа PL SQL

create or replace PROCEDURE ex5b_supplier_update(supplier_id_delete IN VARCHAR2, 
    supplier_id_update IN VARCHAR2) IS 
    CURSOR supplier_cursor IS 
    SELECT supplier_id 
    FROM supplier; 
    supplier_row supplier_cursor%rowtype; 
    BEGIN 
    OPEN supplier_cursor; 
    LOOP 
    FETCH supplier_cursor INTO supplier_row; 
    EXIT WHEN supplier_cursor%notfound; 

IF ex5b_supplier_exist(supplier_id_delete) THEN 


    UPDATE supplier 
    SET supplier_id = supplier_id_update 
    WHERE supplier_id = supplier_id_delete; 

    UPDATE PURCHASE_ORDER 
    SET supplier_id = supplier_id_update 
    WHERE supplier_id = supplier_id_delete; 

    UPDATE PRODUCT 
    SET supplier_id = supplier_id_update 
    WHERE supplier_id = supplier_id_delete; 

    DBMS_OUTPUT.PUT_LINE('UPDATED'); 
    ELSE 
    DBMS_OUTPUT.PUT_LINE('NOT UPDATED'); 
END IF; 
END LOOP; 
CLOSE supplier_cursor; 
END; 

Процедура дает мне следующее сообщение об ошибке:

Error starting at line : 2 in command - BEGIN ex5b_supplier_update('S500','S600');

END;

Error report - ORA-02292: integrity constraint (SYSTEM.PRODUCT_FK) violated - child record found ORA-06512: at "SYSTEM.EX5B_SUPPLIER_UPDATE", line 15 ORA-06512: at line 2 02292. 00000 - "integrity constraint (%s.%s) violated - child record found" *Cause: attempted to delete a parent key value that had a foreign dependency. *Action: delete dependencies first then parent or disable constraint.

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

Таким образом, мой вопрос заключается в том, как я могу изменить имя поставщика и все его внешние ключи одновременно, чтобы избежать этой ошибки?

+0

1. Вставьте новый родительский элемент. 2. Обновите детей до нового родителя. 3. Удалите старый родитель. Надежда никто не добавил нового ребенка между шагами 2 и 3. Или отложенные ограничения. –

ответ

2

В реляционной базе данных первичный ключ гарантированно будет три вещи:

1) Not nullable 
2) Unique 
3) UNCHANGING 

Это третье правило, которое вы здесь нарушение, и от ошибок вы получаете, возможно, вы видите, почему. Этот путь - безумие. Не меняйте значение первичного ключа. Измените значения атрибутов, которые вам нравятся, так что теперь строка выглядит совершенно иначе - но не меняйте первичный ключ. Если вам нужно подумать, что вам нужно изменить первичный ключ, то вы действительно говорите, что ваш первичный ключ не является, по сути, основным. Это может быть уникальный ключ, но по определению это не первичный ключ.

Первичные ключи не меняются.

Удачи.

EDIT

Если вы действительно хотите, чтобы «изменить» первичный ключ без отключения ограничений и т.д., вот что вы делаете:

  1. Начало транзакции.
  2. Создайте новую строку в таблице с новым идентификатором.
  3. Скопируйте все атрибуты ЗА ИСКЛЮЧЕНИЕМ ИДЕНТИФИКАТОРЫ ПЕРВИЧНОГО КЛЮЧА из строки «оригинал» в «новую» строку.
  4. Обновить все строки в таблицах с ограничениями внешнего ключа, которые ссылаются на «исходную» строку для ссылки на «новую» строку, то есть изменить «старое» значение ID на «новое» значение идентификатора.
  5. Удалите «оригинальную» строку.
  6. COMMIT транзакция.

При этом вы не нарушаете никаких правил относительно первичных ключей, и в конце транзакции первичный ключ, по-видимому, был изменен, и все FK обновлены.

Удачи.

+0

Существует способ сделать это, это требование моего задания. Конечно, вы не должны этого делать, но я не спрашивал, нужно ли вам, я спросил, как я могу. – user2725919

+2

Единственный способ сделать это - либо отключить все ограничения внешнего ключа зависимых рассказов, либо продолжить изменение и убедиться, что перед тем, как вы включите ограничения внешнего ключа, поместите соответствующие значения первичного ключа во все таблицы зависимостей, а затем ENABLE external key Constraints , НО ЭТО НЕ ВСЕ ПРИНИМАЕТСЯ ИГРАТЬ С ПЕРВИЧНЫМ КЛЮЧОМ. –

+0

@ user2725919: отредактировано, чтобы показать, как это сделать, не нарушая правила первичных ключей или отключая ограничения. Удачи. –

Смежные вопросы