创建发票表条目的存储过程

时间:2015-11-07 22:03:55

标签: sql oracle plsql foreign-keys ora-02291

我必须创建一个存储过程来创建发票表条目。该过程应允许用户通过提供新的发票号x和客户ID y来插入记录。日期应为当前系统日期,小计,税金和总计字段应为0.

我已经为这个问题编写了这段代码:

SET SERVEROUTPUT ON

CREATE OR REPLACE PROCEDURE InoviceEntry_step1(X in number, Y in number)
as
begin    
  insert into INVOICE(inv_number, cus_code, inv_date,
                      inv_subtotal, inv_tax, inv_total)
  values (X, Y, sysdate, 0, 0, 0);    
end;
/

CALL InoviceEntry_step1 (1009,11111);

电话会引发错误:

Error report -
SQL Error: ORA-02291: integrity constraint (USER.SYS_C00109369) violated - parent key not found
ORA-06512: at "USER.INOVICEENTRY_STEP1", line 6
02291. 00000 - "integrity constraint (%s.%s) violated - parent key not found"
*Cause:    A foreign key value has no matching primary key value.
*Action:   Delete the foreign key or add a matching primary key.

我做错了什么,可能有更好的方法来做到这一点吗?

2 个答案:

答案 0 :(得分:2)

INVOICE表列cus_code上有一个外键,它引用另一个表中的另一列(我猜测CUSTOMER表的主键或类似的东西)。您在该表中没有客户ID为11111的客户。在运行此过程之前,您需要向另一个表的引用列添加值为11111的行。

答案 1 :(得分:0)

也许,你面临着不受控制的输入情况。您的程序需要自己控制它们。处理错误有两种方法。

首先,您可以按Exceptions处理错误。

CREATE OR REPLACE PROCEDURE InoviceEntry_step1
   (X in number, Y in number)
AS
  parent_not_found exception;
  pragma exception_init(parent_not_found, -2291);
BEGIN
  INSERT INTO INVOICE(inv_number, cus_code, inv_date, inv_subtotal, inv_tax, inv_total)
  VALUES(X, Y, SYSDATE, 0, 0, 0);
  COMMIT;
EXCEPTION 
  WHEN parent_not_found
    THEN  DBMS_OUTPUT.PUT_LINE('Error: CUSTOMER_ID = ' || Y || ' is not found.');
  WHEN OTHERS
    THEN DBMS_OUTPUT.PUT_LINE('Error');
END;

其次,您可以自己处理错误。例如,我在插入发票之前检查客户表中的“cus_code”。

CREATE OR REPLACE PROCEDURE InoviceEntry_step1
   (X in number, Y in number)
AS
 CURSOR c_customer IS (SELECT ID FROM CUSTOMER WHERE ID = Y AND ROWNUM =1);
 v_ID NUMBER;
BEGIN
  OPEN c_customer;
  FETCH c_customer INTO v_ID;
  IF c_customer%NOTFOUND
  THEN
     --Option1: If it shouldn't happend with your designed, you can just let error message without insert data.
     DBMS_OUTPUT.PUT_LINE('Error: CUSTOMER_ID = ' || Y || ' is not found.');
     DBMS_OUTPUT.PUT_LINE('Please create customer profile.');

     --Option2:  You may add customer_id first and insert invoice, if you want but I don't recommend.  
     INSERT INTO CUSTOMER (ID) VALUES(Y);
     DBMS_OUTPUT.PUT_LINE('CUSTOMER_ID = ' || Y || ' has been created.');

     INSERT INTO INVOICE(inv_number, cus_code, inv_date, inv_subtotal, inv_tax, inv_total)
     VALUES(X, Y, SYSDATE, 0, 0, 0);
     DBMS_OUTPUT.PUT_LINE('INVOICE_NO = ' || X || ' has been created.');
  ELSE
     INSERT INTO INVOICE(inv_number, cus_code, inv_date, inv_subtotal, inv_tax, inv_total)
     VALUES(X, Y, SYSDATE, 0, 0, 0);
     DBMS_OUTPUT.PUT_LINE('INVOICE_NO = ' || X || ' has been created.');
  END IF;
  CLOSE c_customer;
  COMMIT;
END;

但是,不要忘记“提交”交易。