以下PL / SQL触发器代码中的错误是什么

时间:2017-08-13 02:06:31

标签: sql oracle plsql oracle11g

CREATE OR REPLACE TRIGGER t_for_debit
BEFORE UPDATE 
ON account
FOR EACH ROW
WHEN (new.acc_bal>0)
DECLARE
amt ACCOUNT.ACC_BAL%TYPE;
BEGIN
    select acc_bal into amt from account where accno=:old.accno;
if :old.acc_bal-:new.acc_bal then
    DBMS_OUTPUT.PUT_LINE('PREVIOUS AMOUNT ->'||:old.acc_bal||' DEDUCE BALANCE ||:new.acc_bal||' NEW BALANCE IS ' ||:old.acc_bal-:new.acc_bal );
else
    insert into loan values(:old.acc_name,:old.acc_bal-:new.acc_bal,:old.accno)
    DBMS_OUTPUT.PUT_LINE('TXN SUCCESSFULLY BUT DUE TO DEBIT MONEY MORE THAN ACCOUNT MONEY');
    DBMS_OUTPUT.PUT_LINE('WE OPENED YOUR LOAN ACCOUNT. PLEASE FEED THE LOAN BEFORE FURTHER USE');
    DBMS_OUTPUT.PUT_LINE('LOAN CUSTOMER NAME '||:old.acc_name||' HAVING LOAN AMOUT '||:old.acc_bal-:new.acc_bal||' ASSOCAITE WITH '||:old.accno || '        ACCOUNT NO');
END IF;
END;
/

当我在SQL * Plus命令提示符下编译此代码时,显示错误。

6/93     PLS-00103: Encountered the symbol "NEW" when expecting one of the
         following:
         ) , * & = - + < / > at in is mod remainder not rem =>
         <an exponent (**)> <> or != or ~= >= <= <> and or like like2
         like4 likec as between from using || member submultiset

2 个答案:

答案 0 :(得分:0)

首先,我想指出未使用SELECT语句的结果,因此应将其删除。

错误发生在IF表达式

if :old.acc_bal-:new.acc_bal then

表达式必须求值为布尔值。表达式:old.acc_bal - :new.acc_bal是数字结果。我怀疑你的意思是:old.acc_bal > :new.acc_bal

答案 1 :(得分:0)

您的代码存在多个问题。

  • if :old.acc_bal-:new.acc_bal THEN ..不是有效的声明 它被修改为

    if :old.acc_bal-:new.acc_bal > 0 THEN

您的触发器将通过上述更改进行编译,但是。

  • select acc_bal into amt语句将引发错误ORA-04091: table HR.ACCOUNT is mutating, trigger/function may not see it。在帐户表上运行更新语句时会发生这种情况。在触发器的上下文中,它不是必需的,因为我们可以从:old.acc_bal and :new.acc_bal获得所有必需的值。所以,它被评论。

  • 您无法将数字差异的结果与DBMS_OUTPUT.PUT_LINE()内的字符串连接起来。它会抛出异常ORA-06502: PL/SQL: numeric or value error。所以,在这里我更改了代码,将差异的结果存储到amt变量中,并在DBMS_OUTPUT中重复使用。

    SET DEFINE OFF
    SET SERVEROUTPUT ON
    CREATE OR REPLACE TRIGGER t_for_debit
    BEFORE UPDATE 
    ON account
    FOR EACH ROW
    WHEN (new.acc_bal > 0)
    DECLARE
    amt ACCOUNT.ACC_BAL%TYPE; 
    BEGIN
    amt := :old.acc_bal-:new.acc_bal;
        --select acc_bal into amt from account where accno = :old.accno;
    if amt > 0 then
       DBMS_OUTPUT.PUT_LINE('PREVIOUS AMOUNT ->'||:old.acc_bal||' DEDUCE BALANCE '||:new.acc_bal||' NEW BALANCE IS ' || amt);
    else
        insert into loan(acc_name,acc_bal,accno)  values(:old.acc_name,:old.acc_bal-:new.acc_bal,:old.accno);
        DBMS_OUTPUT.PUT_LINE('TXN SUCCESSFULLY BUT DUE TO DEBIT MONEY MORE THAN ACCOUNT MONEY');
        DBMS_OUTPUT.PUT_LINE('WE OPENED YOUR LOAN ACCOUNT. PLEASE FEED THE LOAN BEFORE FURTHER USE');
        DBMS_OUTPUT.PUT_LINE('LOAN CUSTOMER NAME '||:old.acc_name||' HAVING LOAN AMOUT '||amt||' ASSOCAITE WITH '||:old.accno || '        ACCOUNT NO');
    END IF;
    END;
    /
    

以下是else条件的输出。

     1 rows updated.
     TXN SUCCESSFULLY BUT DUE TO DEBIT MONEY MORE THAN ACCOUNT MONEY
     WE OPENED YOUR LOAN ACCOUNT. PLEASE FEED THE LOAN BEFORE FURTHER USE
     LOAN CUSTOMER NAME INV HAVING LOAN AMOUT -1 ASSOCAITE WITH 1        ACCOUNT NO
相关问题