ORA-02292: 违反完整性约束 - 在 ORACLE SQL Developer 中创建过程时发现子记录?
Posted
技术标签:
【中文标题】ORA-02292: 违反完整性约束 - 在 ORACLE SQL Developer 中创建过程时发现子记录?【英文标题】:ORA-02292: integrity constraint violated - child record found while creating procedures in ORACLE SQL Developer? 【发布时间】:2017-10-22 02:14:52 【问题描述】:我编写了一个输入 CUSTOMER_ID 的过程。然后该过程从表 CUSTOMERS 中删除相应的客户。
CREATE OR REPlACE PROCEDURE DELETE_CUSTOMER
(CUSTOMER_ID NUMBER) AS
TOT_CUSTOMERS NUMBER;
BEGIN
DELETE FROM CUSTOMERS
WHERE CUSTOMERS.CUSTOMER_ID = DELETE_CUSTOMER.CUSTOMER_ID;
TOT_CUSTOMERS := TOT_CUSTOMERS - 1;
END;
/
我必须执行删除 id 为 1 的客户的程序。
EXECUTE DELETE_CUSTOMER(01);
当我这样做时,我得到一个错误
Error starting at line : 120 in command -
BEGIN DELETE_CUSTOMER(01); END;
Error report -
ORA-02292: integrity constraint (TUG81959.ORDERS_FK_CUSTOMERS) violated - child record found
ORA-06512: at "TUG81959.DELETE_CUSTOMER", line 5
ORA-06512: at line 1
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.
我知道这是因为表 ORDERS 上有一个 CUSTOMER_ID 的外键,这意味着无法删除该客户,因为他已下订单。 如何编写代码,以便我可以先删除相应的 ORDER_DETAILS,然后再删除相应的 ORDERS,以便最终能够从 CUSTOMERS 中删除一条记录?
我尝试重写代码,但我现在迷路了:
CREATE OR REPlACE PROCEDURE DELETE_CUSTOMER
(CUSTOMER_ID_IN NUMBER) AS
TOT_CUSTOMERS NUMBER;
CURSOR C1 IS
DELETE FROM ORDERS
WHERE ORDERS.ORDER_ID = CUSTOMER_ID.ORDER_ID;
CURSOR C2 IS
DELETE FROM ORDER_DETAILS
WHERE ORDER_DETAILS.ORDER_ID = CUSTOMER_ID.ORDER_ID;
CURSOR C3 IS
DELETE FROM CUSTOMERS
WHERE CUSTOMERS.CUSTOMER_ID = DELETE_CUSTOMER.CUSTOMER_ID;
BEGIN
OPEN C1;
OPEN C2;
OPEN C3;
IF C1%FOUND AND C2%FOUND AND C3%FOUND
THEN TOT_CUSTOMERS := TOT_CUSTOMERS - 1;
END IF;
CLOSE C1;
CLOSE C2;
CLOSE C3;
END;
/
以下是供参考的表格:
【问题讨论】:
另一种方法是将约束设置为延迟。 On Deferring and Bulking Up 【参考方案1】:有两种方法可以做到这一点:
您可以在删除时使用级联(drop&create again):
drop constraint order_details_fk_orders;
alter table order_details add constraint order_details_fk_orders
foreign key(order_id) references orders(order_id)
on delete cascade;
delete orders where customer_id = &i_cust_id;
或
您可以先删除您的详细记录:
通过以下程序:
CREATE OR REPLACE PROCEDURE PR_DELETE_CUSTOMER(
I_CUSTOMER_ID orders.customer_id%type,
O_TOT_CUSTOMERS out number
) IS
BEGIN
delete order_details where order_id in ( select order_id from orders where customer_id = I_CUSTOMER_ID );
delete orders where customer_id = I_CUSTOMER_ID;
delete customers where customer_id = I_CUSTOMER_ID;
select count(1) into O_TOT_CUSTOMERS from orders;
END;
然后
var v_tot_customers number;
execute pr_delete_customer(1,:v_tot_customers);
print v_tot_customers;
【讨论】:
不幸的是我不得不使用第二种方式,但我不知道如何将它实现到程序代码中。我已经更新了上面的代码,但现在我完全迷失了。 像这样:***.com/questions/5382906/… @pyuntae 我已经添加了程序。 我收到另一个错误Error(62,31): PL/SQL: ORA-00904: "ORD_DET_CUST_ID": invalid identifier
我将"ORD_DET_CUST_ID"
更改为order_id
并已编译,但是当我尝试执行EXECUTE DELETE_CUSTOMER(01);
过程时,我收到一条错误消息,提示PLS-00306: wrong number or types of arguments in call to 'DELETE_CUSTOMER' ORA-06550: line 1, column 52: PL/SQL: Statement ignored 06550. 00000 - "line %s, column %s:\n%s" *Cause: Usually a PL/SQL compilation error.
【参考方案2】:
在删除父记录之前先删除引用的子记录。
delete from child_table where parent_id='FCS000154';
delete from parent_table where parent_id='FCS000154';
COMMIT;
这是一种简单的方法。
【讨论】:
以上是关于ORA-02292: 违反完整性约束 - 在 ORACLE SQL Developer 中创建过程时发现子记录?的主要内容,如果未能解决你的问题,请参考以下文章