在执行触发期间无法插入NULL,ERROR

时间:2017-10-21 20:26:52

标签: oracle plsql ddl database-trigger

我在表Customers上创建了一个Trigger,这样每次从表客户删除一条记录时,同一条记录都会插入表Customer_Archives中,当前日期为Deletion_Date。

我必须将新客户插入表Customers,然后将其删除。必须将记录正确插入表Customers_Archive。

到目前为止,这是我的脚本:

CREATE TABLE Customer_Archives
(
  customer_id           NUMBER          NOT NULL,
  customer_first_name   VARCHAR2(50),
  customer_last_name    VARCHAR2(50)    NOT NULL,
  customer_address      VARCHAR2(255)   NOT NULL,
  customer_city         VARCHAR2(50)    NOT NULL,
  customer_state        CHAR(2)         NOT NULL,
  customer_zip          VARCHAR2(20)    NOT NULL,
  customer_phone        VARCHAR2(30)    NOT NULL,
  customer_fax          VARCHAR2(30),
  deletion_date         DATE, 
  CONSTRAINT customer_archives_pk 
    PRIMARY KEY (customer_id)
);

CREATE OR REPLACE TRIGGER Customers_before_insert
BEFORE DELETE ON Customers
FOR EACH ROW 
DECLARE 
    ar_row Customers%rowtype;
BEGIN
INSERT INTO Customer_Archives 
VALUES(ar_row.Customer_id,
    ar_row.Customer_First_Name,
    ar_row.Customer_Last_Name,
    ar_row.Customer_Address,
    ar_row.Customer_City,
    ar_row.Customer_State,
    ar_row.Customer_Zip,
    ar_row.Customer_Phone,
    ar_row.Customer_Fax, 
    sysdate());
    dbms_output.put_line('New row is added to Customers_Archive 
    Table with Customer_ID:' ||ar_row.Customer_id ||'on date:' || sysdate());
END;
/

SELECT trigger_name, status FROM user_triggers;

INSERT INTO CUSTOMERS
(customer_id, customer_first_name, customer_last_name, customer_address, 
customer_city, customer_state, customer_zip, customer_phone, customer_fax)
VALUES (27,'Sofia','Chen','8888 Cowden St.','Philadelphia','PA',
'19149',7654321234',NULL);

DELETE FROM CUSTOMERS
WHERE customer_id = 27;

当我尝试删除刚插入的客户时,出现错误:

Error starting at line : 47 in command -
DELETE FROM CUSTOMERS
WHERE customer_id = 27
Error report -
ORA-01400: cannot insert NULL into ("TUG81959"."CUSTOMER_ARCHIVES"."CUSTOMER_ID")
ORA-06512: at "TUG81959.CUSTOMERS_BEFORE_INSERT", line 4
ORA-04088: error during execution of trigger 'TUG81959.CUSTOMERS_BEFORE_INSERT'

1 个答案:

答案 0 :(得分:4)

在DELETE触发器中,您应该在创建存档记录时使用:OLD值:

CREATE OR REPLACE TRIGGER CUSTOMERS_BEFORE_INSERT
  BEFORE DELETE ON CUSTOMERS
  FOR EACH ROW 
BEGIN
  INSERT INTO CUSTOMER_ARCHIVES 
    (CUSTOMER_ID,
     CUSTOMER_FIRST_NAME,
     CUSTOMER_LAST_NAME,
     CUSTOMER_ADDRESS,
     CUSTOMER_CITY,
     CUSTOMER_STATE,
     CUSTOMER_ZIP,
     CUSTOMER_PHONE,
     CUSTOMER_FAX,
     DELETION_DATE)
  VALUES
    (:OLD.CUSTOMER_ID,
     :OLD.CUSTOMER_FIRST_NAME,
     :OLD.CUSTOMER_LAST_NAME,
     :OLD.CUSTOMER_ADDRESS,
     :OLD.CUSTOMER_CITY,
     :OLD.CUSTOMER_STATE,
     :OLD.CUSTOMER_ZIP,
     :OLD.CUSTOMER_PHONE,
     :OLD.CUSTOMER_FAX, 
     SYSDATE());

  DBMS_OUTPUT.PUT_LINE('New row is added to Customers_Archive 
    Table with Customer_ID:' ||:OLD.Customer_id ||'on date:' || SYSDATE());
END;

在原始触发器中,您声明了一个名为ar_row的行变量,但没有为任何字段分配任何内容 - 因此它们都是NULL。在DELETE期间调用BEFORE触发器时,:OLD值具有删除前的值,并且:NEW值全部为NULL。

祝你好运。