2016-11-06 100 views
1

我對PL/SQL非常陌生,我試圖找出在觸發器上使用百分比的正確方法。這是我的問題:PL/SQL計算觸發器的百分比

我想創建一個觸發器,每當新的價格有減少> 20%觸發器將觸發,只有在一個減少。我以爲我的邏輯是正確的,但我不能得到它的工作:

表:

Product: pid, price, pname 

代碼:

set serveroutput on; 

show errors; 

update product 
    set price = 3000 
where pid = 2; 

select * from product; 

create or replace trigger percentage 
after update on product 
    for each row when ((((new.price - old.price)/old.price) * 100)>.20) 
declare 
    x product.pname%type; 
    y varchar(100); 
begin 

y := (((:new.price - :old.price)/:old.price) * 100); 


    dbms_output.put_line('The Product: '||:new.pname|| ' price has decreased by: '|| y ||'%'); 
end; 

我繼續得到這樣的錯誤:

6/3 PLS-00103: Encountered the symbol "=" when expecting one of the f ollowing: := . (@ % ; 
6/54 PLS-00103: Encountered the symbol ";" when expecting one of the f ollowing: . () , * % & = - + </> at in is mod remainder no t rem <an exponent (**)> <> or != or ~= >= <= <> and or like l ike2 like4 likec between || multiset member submultiset 
12/4 PLS-00103: Encountered the symbol "end-of-file" when expecting on e of the following: end not pragma final instantiable order o verriding static member constructor map 
+0

在'when'觸發的'子句:new'和':old'需要被無分號指定,「新」和「舊」。其次,'when'條件具有不匹配的括號。 –

+0

已作出更改,但在價格提高時仍然有效。 – user2402107

+1

如果價格上漲,您的表達'(new.price - old.price)/ old.price'將評估爲正數;如果它超過0.2%(請注意你正在進行的轉換),你的觸發器應該會觸發。如果價格下跌,您的表達式將評估爲負數,該數字總是小於「.20」。附:爲什麼當你用'.20'而不是'20'比較時你乘以100? –

回答

1

觸發器的寫法只會在價格上漲時觸發增加大於百分之一或更多的2/10。讓我們運行一個例子:

如果NEW.PRICE是101和OLD.PRICE是100 WHEN子句中的計算

((((new.price - old.price)/old.price) * 100) 

將計算作爲

((((101 - 100)/100) * 100) 

並且這產生作爲(1/100結果)* 100,這是1.0。因爲1.0大於0.20,觸發器會觸發。

顯然這不是你想到的。

我認爲你想你的WHEN子句改爲

WHEN ((((OLD.PRICE - NEW.PRICE)/OLD.PRICE) * 100) > 20) 

鑑於此,讓我們重新考慮我們的第一個例子:

(((100 - 101)/100) * 100) 

產生-1,且不會引發觸發器,哪個是對的。

現在,我們來看一個觸發器應該觸發的例子。我們的老價格爲100,我們新的價格是70,而我們的計算變得

(((100 - 70)/100) * 100) 

產生的30的結果,所以觸發火災。

給一個鏡頭。

祝你好運。

1

PL/SQL中的賦值符號是「:=」不是「=」,因爲您在開始後的第一行代碼中使用了

+0

進行了更改,仍然沒有改變任何東西 – user2402107

+1

@ user2402107 - 「仍然沒有改變**任何**」是** bs **(技術術語) - 如果確實進行了更改,第一個錯誤(關於遇到位置3的第6行符號'=')應該消失。 – mathguy

2

邏輯的最簡單的表現形式似乎是:

new.price < 0.8 * old.price 

我不喜歡錶達變化,以作爲「下降比......」的想法。語義很奇怪。 「

」降低到低於「似乎是一種更好的表達方法。

0
for each row when ((((new.price - old.price)/old.price) * 100) < -.20) 
declare 
    y varchar(100); 
begin 


y:= (((:new.price - :old.price)/:old.price) * 100); 
0

把所有的好建議,到目前爲止在一起,你應該得到這樣的事情:

create or replace trigger percentage after update on product for each row 
when (new.price < old.price * 0.8) 
declare 
    l_percent number(6,1) := 100 * (:old.price - :new.price)/nullif(:old.price,0); 
begin 
    dbms_output.put_line('Product '||:new.pname||' price has decreased by '|| l_percent ||'%'); 
end;