我正在尝试编写一个PL / SQL过程,该过程将从供应商表中查找现有主键“supplier_id”并将其替换为新主键。主键“supplier_id”也是其他几个表的外键。因此我也需要更新外键位置。这是我为解决这个问题而编写的程序:
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;
该程序给出了以下错误:
从命令行中的第2行开始出错 - 开始 ex5b_supplier_update( 'S500', 'S600');
END;
错误报告 - ORA-02292:完整性约束(SYSTEM.PRODUCT_FK) 违反 - 儿童记录发现ORA-06512:at “SYSTEM.EX5B_SUPPLIER_UPDATE”,第15行ORA-06512:第2行 02292. 00000 - “违反完整性约束(%s。%s) - 发现子记录” *原因:尝试删除具有外部的父键值 依赖。 *操作:先删除依赖项,然后删除父项或禁用约束。
完全可以理解,您无法删除用作外键的主键。但我也无法更改没有主键的外键。
所以我的问题是如何同时更改supplier_id及其所有外键以避免此错误?
答案 0 :(得分:2)
在关系数据库中,主键保证是三件事:
1) Not nullable
2) Unique
3) UNCHANGING
这是你在这里违反的第三条规则,而你从错误中得到的错误也许就是为什么。这种方式就是疯狂。 请勿更改主键的值。您可以随意更改属性值,以便该行现在看起来完全不同 - 但不要更改主键。如果你需要认为你需要更改主键,那么你真正说的是你的主键实际上并不是主键。它可能是一个唯一的密钥,但根据定义它不是主键。
主键不会被更改。
祝你好运。
如果你真的想要改变"没有禁用约束等的主键,这里是你做的:
以这种方式完成后,您不会违反任何有关主键的规则,并且在交易结束时,主键似乎已被更改,所有FK都会更新。
祝你好运。