2014-03-05 52 views
0

我有這個觸發器,它應該這樣做:mysql的觸發器出現錯誤

前的新條目在進入日誌表創建,它會從該表中的driver_id,把它放入if語句和然後根據結果將新條目中的允許字段設置爲Y或No。

create trigger xxx before insert on entrylog for each row 
if exists (select * 
       from driver 
       join card_driver 
       on driver.id = card_driver.driver_id 
       join card 
       on card_driver.card_id = card.id 
      where driver.id = new.driver_id) then 
    set new.allowed = 'Y'; 
end if 

唯一的問題是,它的劑量工作。如果我嘗試了把它放到phpMyAdmin的我不斷收到此錯誤:

Error 

SQL query: Documentation 

CREATE trigger allowedupdate before INSERT ON entrylog 
FOR each 
ROW 
IF EXISTS (

SELECT * 
FROM driver 
JOIN card_driver ON driver.id = card_driver.driver_id 
JOIN card ON card_driver.card_id = card.id 
WHERE driver.id = new.driver_id 
) 
THEN 
SET new.allowed = 'Y'; 

MySQL said: Documentation 
#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 9 

if語句是從其中取出,並應產生相同的結果(只是沒有呼應消息)

$sql ="SELECT * 
    FROM driver AS d 
INNER 
    JOIN card_driver AS cd 
    ON cd.driver_id = d.id 
INNER 
    JOIN card AS c 
    ON c.id = cd.card_id  
WHERE d.ID = $id"; 
mysql_select_db('damp'); 
$result = mysql_query($sql, $conn); 
$row = mysql_fetch_assoc($result); 
switch($row['state_id']) 
{ 
case "1": 
    echo "<strong><font color=\"green\">Authorisation Granted!</font></strong>"; 
    break; // This should be a Y , the rest are N 
case "2": 
    echo "<strong><font color=\"red\">Your card has expired and authorisation is denied</font></strong>"; 
    break; 
case "3": 
    echo "<strong><font color=\"red\">Your card has been cancelled and authorisation is denied</font></strong>"; 
    break; 
default: 
    echo "<strong><font color=\"red\">The Card ID does not exist</font></strong>"; 
} 

回答

0

這是一個非常微妙的問題,但你錯過了最後的end if。它在那裏,但分號結束觸發器定義。這就是爲什麼MySQL有delimiter關鍵字。

觸發定義應該是這樣的:

delimiter $$ 
create trigger xxx before insert on entrylog for each row 
begin 
    if exists (select * 
        from driver 
        join card_driver 
        on driver.id = card_driver.driver_id 
        join card 
        on card_driver.card_id = card.id 
       where driver.id = new.driver_id) then 
     set new.allowed = 'Y'; 
    end if; 
end;$$ 
delimiter ; 

我還添加了begin/end。雖然不是絕對必要的,但我總是使用它們。而且,如果你的原始語句有它們,你將會遇到編譯時錯誤。

+0

據我所知,只有當分隔的語句數大於1(1)時,才需要'begin' - 'end'塊。在查詢過程中,set ..'是stmt 1,'end if'是2.所以我們需要第二個分號,因此需要一個'begin' - 'end'塊。 –

+0

@Ravinder。 。 。原始觸發器由一個語句組成,這是一個'if'語句。觸發器的定義以'set'語句的分號結束。 'begin' /'end'塊不是必需的,但我會一直包含它。這樣的塊可以包含一個語句。 –

+0

這是真的。包含開始結束塊總是很好,即使對於單個可執行語句也是如此。但是'set new.allowed = if(!exists(...),'Y',new.allowed);'是一個簡單的解決方案,除非OP會向body添加更多的語句。 –