在Trigger和仍然更新表中引发应用程序错误

时间:2014-07-26 22:35:48

标签: sql oracle triggers

我在这里面临一些问题,当时客户没有在60天内付款。触发器将更新客户表并仍然提升 错误-20003。

我意识到如果发生引发异常,更新功能将被取消。

有没有办法绕过这样做?

CREATE OR REPLACE TRIGGER cut_supply
BEFORE INSERT ON reading
FOR EACH ROW
DECLARE
    cust_ID BILL.custID%TYPE;
    sent_date BILL.sentDate%TYPE;
    payment_date BILL.paymentdate%TYPE;
    bad_Status CUSTOMER.badStatus%TYPE;
    first_name CUSTOMER.firstName%TYPE;
    last_name CUSTOMER.lastName%TYPE;
    NRIC_No CUSTOMER.NRIC%TYPE;
  pRate_ID CUSTOMER.pRateID%TYPE;
  no_new_reading EXCEPTION;
CURSOR cust_cursor IS
        SELECT b.custID, b.sentDate, b.paymentDate, c.badStatus, c.firstName, c.lastName, c.NRIC, c.pRateID
        FROM bill b, customer c, reading r
        WHERE (sysdate - sentDate) > 20
        AND paymentDate is null
        AND b.custID = c.custID
        AND r.readingID = b.readingID
        FOR UPDATE OF c.badStatus;
BEGIN
   OPEN cust_cursor;  
   LOOP
        FETCH cust_cursor INTO cust_ID, sent_date, payment_date,
                             bad_Status, first_name, last_name, NRIC_No, pRate_ID;
        IF cust_cursor%NOTFOUND THEN
            EXIT;
        END IF;
        IF cust_cursor%ROWCOUNT = 0 THEN
            DBMS_OUTPUT.PUT_LINE( 'No customer found');
        ELSE
            UPDATE customer
            SET pRateID= 801, badStatus='Non Payment'
            WHERE CURRENT OF cust_cursor;
            RAISE no_new_reading;
        END IF;
    END LOOP;
    CLOSE cust_cursor;
   COMMIT;
EXCEPTION
  WHEN no_new_reading THEN
  RAISE_APPLICATION_ERROR ( -20003,
        'Customer ' || first_name||''||last_Name ||
         ' water supply has been cut off' );
   WHEN OTHERS THEN
      DBMS_OUTPUT.PUT_LINE(SQLERRM);
END;
/

1 个答案:

答案 0 :(得分:0)

这可以通过以下方式解决,创建一个更新客户表的程序

create or replace procedure update_customer
as
pragma autonomous_transaction;
begin
update customer c set c.badStatus='Non Payment', c.pRateID=801 
where c.custID=
(
  select distinct c.custID
  FROM bill b, reading r
        WHERE (sysdate - sentDate) > 20
        AND paymentDate is null
        AND b.custID = c.custID
        AND r.readingID = b.readingID
);
commit;
end;
/

使用触发器调用过程本身。

CREATE OR REPLACE TRIGGER cut_supply
BEFORE INSERT ON reading
FOR EACH ROW
DECLARE
    cust_ID BILL.custID%TYPE;
    sent_date BILL.sentDate%TYPE;
    payment_date BILL.paymentdate%TYPE;
    bad_Status CUSTOMER.badStatus%TYPE;
    first_name CUSTOMER.firstName%TYPE;
    last_name CUSTOMER.lastName%TYPE;
    NRIC_No CUSTOMER.NRIC%TYPE;  
    reject_new_reading_excep EXCEPTION;
CURSOR cust_cursor IS 
     SELECT b.custID, b.sentDate, b.paymentDate, c.badStatus, c.firstName, c.lastName, c.NRIC
        FROM bill b, customer c, reading r
        WHERE (sysdate - sentDate) > 20
        AND paymentDate is null
        AND b.custID = c.custID
        AND r.readingID = b.readingID;
BEGIN
   OPEN cust_cursor;   
   LOOP
        FETCH cust_cursor INTO cust_ID, sent_date, payment_date, 
                             bad_Status, first_name, last_name, NRIC_No;

        IF cust_cursor%NOTFOUND THEN 
            EXIT;
        END IF;
        IF cust_cursor%ROWCOUNT = 0 THEN
            DBMS_OUTPUT.PUT_LINE( 'No customer found');
        ELSE
        update_customer;
        RAISE reject_new_reading_excep;
        END IF;
    END LOOP;
    CLOSE cust_cursor;
   COMMIT;
EXCEPTION
  WHEN reject_new_reading_excep THEN
  RAISE_APPLICATION_ERROR ( -20003, 
        'Customer ' || first_name||''||last_Name ||
        ' water supply has been cut off' );
   WHEN OTHERS THEN
      DBMS_OUTPUT.PUT_LINE(SQLERRM);
END;
/