ORA-02292:违反完整性约束 - 在 ORACLE SQL Developer 中创建过程时发现子记录?

pyu*_*tae 3 oracle plsql stored-procedures constraints ora-02292

我已经编写了一个以 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;
/
Run Code Online (Sandbox Code Playgroud)

我必须执行删除 ID 为 1 的客户的过程。

EXECUTE DELETE_CUSTOMER(01);
Run Code Online (Sandbox Code Playgroud)

当我这样做时,我收到一个错误

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.
Run Code Online (Sandbox Code Playgroud)

我知道这是因为表 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;
/
Run Code Online (Sandbox Code Playgroud)

以下是供参考的表格: 在此处输入图片说明

Bar*_*han 5

有两种方法可以做到这一点:

您可以在删除时使用级联(再次删除和创建):


   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;
Run Code Online (Sandbox Code Playgroud)

或者

您可以先删除您的详细记录:


使用以下程序:

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;
Run Code Online (Sandbox Code Playgroud)

进而

 var v_tot_customers number;  
 execute pr_delete_customer(1,:v_tot_customers);  
 print v_tot_customers;
Run Code Online (Sandbox Code Playgroud)