2012-12-03 47 views
2

我在我的程序中遇到了這個問題。PL/pgSQL觸發功能不能正常工作

該函數的目的是實現一個觸發器,檢查用戶(utente)是否有足夠的錢在自己的帳戶(saldo)上以便將自己添加到騎乘(boleia)。

我可以從我的函數的行爲中收集用戶(Utente)和乘車(Boleia),但是他們的屬性,特別是他的平衡(saldo)沒有被正確訪問。這是因爲,每次我嘗試添加用戶時,都會遇到例外情況,這意味着用戶沒有足夠的資金投入。

我想不出任何我可能會做錯的事情。 Utente和Boleia表都被正確插入,每個屬性都被插入,但我似乎無法在我的函數中訪問它們。

下面是代碼的功能:

create or replace function assocpass_trigger_proc() returns trigger 
as $$ 
declare 
    x record; 
    y record; 
    balancetemp numeric; 
begin 
    select into x * from Utente where(nick=new.nick_passenger); 
    select into y * from Boleia 
    where(nick=new.nick_planner and date_time=new.date_time); 
    select x.balance into balancetemp; 
    if(found and (balancetemp>=y.cost_passenger)) then 
     update Utente set balance = balancetemp-y.cost_passenger 
     where Utente.nick = new.nick_passenger; 
     insert into InscricaoP(nick_passenger,nick_planner,data_hora) 
     values(new.nick_passenger, new.nick_planner, new.date_time); 
    elseif(found and (x.saldo<y.custo_passageiro)) then 
     raise exception 'O Utente não tem saldo suficiente'; 
    else 
     raise exception 'A Boleia não existe'; 
    end if; 
end 
$$ language plpgsql; 

這裏是關係的插入:

insert into InscricaoP(nick_planner,date_time,nick_passenger) 
values('zero','15/06','cinco'); 

兩個nick_planner和nick_passenger來自 「用戶」(Utilizador)實體 Date_time和cost_passenger來自「ride」(Boleia)實體。

+0

這不是PLSQL,它的PL/pgSQL的它是相當不同的方言......正確標記你的問題,以避免誤解。 – a1ex07

+0

'/'被自動刪除。但下次我會更加小心,我的道歉。 – Ehpansei

+0

這不是關於'/'。 'PL/pgSQL'或者簡單的'plpgsql'是PostgreSQL的默認過程語言。 「PL/SQL」與Oracle相當。 –

回答

3

特殊變量FOUND在每個SELECT INTO命令後面設置。如果您只在最後一個之後檢查,則無法正確測試。

我想你的函數可以工作是這樣的:

CREATE OR REPLACE FUNCTION assocpass_trigger_proc() 
    RETURNS trigger AS 
$func$ 
BEGIN 

UPDATE utente u 
SET balance = balance - b.cost_passenger 
FROM boleia b 
WHERE u.nick = NEW.nick_passenger 
AND b.nick = NEW.nick_planner 
AND b.date_time = NEW.date_time 
AND u.balance >= b.cost_passenger; 

IF FOUND THEN 
    INSERT INTO inscricaop(nick_passenger, nick_planner, data_hora) 
    VALUES (NEW.nick_passenger, NEW.nick_planner, NEW.date_time); 

ELSIF EXISTS (
    SELECT 1 
    FROM utente u, boleia b 
    WHERE u.nick = NEW.nick_passenger 
    AND b.nick = NEW.nick_planner 
    AND b.date_time = NEW.date_time 
    AND u.saldo < b.custo_passageiro) THEN 

    RAISE EXCEPTION 'O Utente não tem saldo suficiente'; 
ELSE 
    RAISE EXCEPTION 'A Boleia não existe'; 
END IF; 

END 
$func$ LANGUAGE plpgsql; 
0

我會通過向utente表添加一個檢查約束來解決這個問題,使得餘額必須大於或等於零,並嘗試通過乘車的成本借記賬戶。如果資金不足,將會引發違反約束的錯誤。

+0

是的,我忘了補充一點,在創建表格時已經包含了檢查約束。 當我更新用戶時,這是我的意圖。用乘坐的成本減去他的餘額。對我來說,問題似乎並不存在,但它們沒有被正確訪問。但我不知道爲什麼 – Ehpansei

+0

好吧,這是有幫助的。我嘗試在函數外部進行更新,並且它工作正常。因此,這導致我認爲問題出在if(已發現)測試之前的3選擇入。 理想情況下,發現將引用3選擇進入(第三個可能是無用的),但我不知道它是否像那樣工作。 – Ehpansei