替换主键PL SQL

时间:2015-10-04 23:51:12

标签: oracle plsql

我正在尝试编写一个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及其所有外键以避免此错误?

1 个答案:

答案 0 :(得分:2)

在关系数据库中,主键保证是三件事:

1) Not nullable
2) Unique
3) UNCHANGING

这是你在这里违反的第三条规则,而你从错误中得到的错误也许就是为什么。这种方式就是疯狂。 请勿更改主键的值。您可以随意更改属性值,以便该行现在看起来完全不同 - 但不要更改主键。如果你需要认为你需要更改主键,那么你真正说的是你的主键实际上并不是主键。它可能是一个唯一的密钥,但根据定义它不是主键。

主键不会被更改

祝你好运。

修改

如果你真的想要改变"没有禁用约束等的主键,这里是你做的:

  1. 开始交易。
  2. 使用新ID在表格中创建一个新行。
  3. 从"原始"复制除主要ID ID列之外的所有属性。排到"新"行。
  4. 使用引用"原始"的外键约束更新表中的所有行。行引用" new"排,即改变" old" ID值为" new" ID值。
  5. 删除"原文"行。
  6. 执行交易。
  7. 以这种方式完成后,您不会违反任何有关主键的规则,并且在交易结束时,主键似乎已被更改,所有FK都会更新。

    祝你好运。