簡體   English   中英

未引發觸發 if-else 語句錯誤

[英]Trigger if-else statement error not being raised

我已經創建了一個程序和一個觸發器,我打算支付票價,輸入的票價金額必須大於或等於支付表中的確切金額

我的付款表

從表中我的意思是,用戶需要輸入足夠的數量才能繼續存儲過程,如果輸入的數量低於該數量,則會引發觸發器錯誤!

程序

CREATE OR REPLACE PROCEDURE PRC_PAY_TRIP
    (CUST_ID IN NUMBER,PAYMENT_ID IN NUMBER,PAYMENT_TYPE IN VARCHAR2,AMT_PAY IN NUMBER)
AS
    v_paymentstatus VARCHAR2(15) := 'Paid';
    v_temppaymentid NUMBER(4) := PAYMENT_ID;
    v_truenumber NUMBER(10);
    
    no_null_on_custID EXCEPTION;
    no_null_on_payID EXCEPTION;
    invalid_paymentid EXCEPTION;
    invalid_paymenttype EXCEPTION;
    invalid_paymentamt EXCEPTION;
    
BEGIN
    v_truenumber := v_temppaymentid-1000;    
    
    IF CUST_ID < 0
    THEN
        RAISE no_null_on_custID;
    END IF;
    
    IF PAYMENT_ID < 0
    THEN
        RAISE no_null_on_payID;
    END IF;
    
    IF CUST_ID ^= v_truenumber THEN
        RAISE invalid_paymentid;
    END IF;
    
    IF PAYMENT_TYPE ^= 'Cash' AND PAYMENT_TYPE ^= 'E-Wallet' THEN
        RAISE invalid_paymenttype;
    END IF;
    
    IF AMT_PAY < 0 THEN
        RAISE invalid_paymentamt;
    END IF;

    UPDATE Payment
    SET paymenttype = PAYMENT_TYPE,paymentdate = TO_CHAR(sysdate,'DD/MON/YYYY'), paymentstatus = v_paymentstatus
    where paymentid = PAYMENT_ID;
   
EXCEPTION    
    WHEN no_null_on_custID then
        DBMS_OUTPUT.PUT_LINE('Invalid Customer ID');
    
    WHEN no_null_on_payID then
        DBMS_OUTPUT.PUT_LINE('Invalid Payment ID');
    
    WHEN invalid_paymenttype then
        DBMS_OUTPUT.PUT_LINE('You can either choose Cash or E-Wallet only!');
    
    WHEN invalid_paymentid then
        DBMS_OUTPUT.PUT_LINE('Payment id is not yours, just add 1000 from your Customer ID and that will be your Payment ID');
    
    WHEN invalid_paymentamt then
        DBMS_OUTPUT.PUT_LINE('Amount pay cannot be negative value!');
END;
/

扳機

CREATE OR REPLACE trigger trg_payment_validation
before update on payment
for each row
BEGIN 
    if :NEW.paymentamount < :OLD.paymentamount then >>> this error could not be raised even after
                                                        the amount entered is lower than the
                                                        actual amount
        RAISE_APPLICATION_ERROR(
          -20950,
          'Insufficient amount entered, pls pay the exact amount'
        );
    elsif :OLD.paymentstatus = 'Paid' then
        RAISE_APPLICATION_ERROR(
          -20950,
          'You cannot pay the fares as you already paid before this, have a nice day'
        );
    end if;
END;
/

當您手動更新表時,觸發器會按預期工作。

當從過程中調用時,觸發器不會報告無效金額,並顯示已支付的全部金額,即使它沒有——支付金額沒有改變,但其他列是。

那是因為你程序的更新語句是:

UPDATE Payment
SET paymenttype = PAYMENT_TYPE,
  paymentdate = TO_CHAR(sysdate,'DD/MON/YYYY'),
  paymentstatus = v_paymentstatus
where paymentid = PAYMENT_ID;

您沒有告訴它更新金額,因此觸發器沒有修改后的:new值 - 舊值和新值相同。 您需要在更新中包括該列:

UPDATE Payment
SET paymenttype = PAYMENT_TYPE,
  paymentdate = TO_CHAR(sysdate,'DD/MON/YYYY'),
  paymentamount = amt_pay,
  paymentstatus = v_paymentstatus
where paymentid = PAYMENT_ID;

數據庫<>小提琴


TO_CHAR(sysdate,'DD/MON/YYYY')看起來很奇怪 - 表列應該是日期而不是字符串,因此您不應該將該值轉換為字符串; 如果該列是日期,那么您將依靠客戶端的 NLS 設置將其轉換回來。 如果您試圖忽略當前時間,那么您可以改為執行TRUNC(sysdate)

您也不應該依賴過程主體中的dbms_output - 您無法控制調用它的人是否啟用了 output,因此他們可能永遠看不到問題。 當您在觸發器中引發異常時,您可以在其他錯誤的過程中執行相同的操作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM