如何编写使用条件和更新的更新

时间:2014-11-08 19:29:38

标签: sql postgresql sql-update

我有一个在触发触发器后调用的函数:

UPDATE scores
                SET points = IF (NEW.success = TRUE, points + 5, points)
                    WHERE match_id = (SELECT match_id FROM player_instance WHERE id = NEW.kicker_id ) AND 
                    team_id = (SELECT team_id FROM player_instance WHERE id = NEW.kicker_id); 

但是我收到了这个错误:

ERROR:  function if(boolean, integer, integer) does not exist
LINE 2:                SET  points = IF (NEW.success = TRUE, points ...
                                 ^
HINT:  No function matches the given name and argument types. You might need to add explicit type  casts.
QUERY:  UPDATE scores
                SET  points = IF (NEW.success = TRUE, points + 3, points)
                    WHERE match_id = (SELECT match_id FROM player_instance WHERE id =      NEW.kicker_id ) AND 
                      team_id = (SELECT team_id FROM player_instance WHERE id = NEW.kicker_id)
CONTEXT:  PL/pgSQL function insert_kicks() line 3 at SQL statement

我猜这是因为没有类似的' if' function(此代码从mysql脚本中复制)。

我该如何实现?

2 个答案:

答案 0 :(得分:1)

我认为您正在寻找的是使用CASE声明:

UPDATE scores
                SET points = case when NEW.success is TRUE then points + 5 else points end 
                    WHERE match_id = (SELECT match_id FROM player_instance WHERE id = NEW.kicker_id ) AND 
                    team_id = (SELECT team_id FROM player_instance WHERE id = NEW.kicker_id); 

答案 1 :(得分:1)

IF在标准SQL中不可用,也不需要(这是MySQL的奇怪之处),而是使用CASE - 正如@Houari已经提供的那样。

然而,无条件地执行UPDATE意味着大量无用的更新,所有人都会以全价编写新的行版本,即使没有任何变化。此外,两个子选择是不必要的昂贵 它应该是:

UPDATE scores s
SET    points = points + 5
FROM   player_instance pi
WHERE  pi.id = NEW.kicker_id
AND    s.match_id = pi.match_id 
AND    s.team_id  = pi.team_id 
AND    NEW.success;

这样,如果条件不满足,UPDATE不会触及任何行。便宜得多。
Details for UPDATE in the manual.