title: update in PostgreSQL function seems to not work
body: <p>To learn how to use function in PostgreSQL, we have to do an exercise with the following statement:</p>
  <p>We have a table Skieur (skier), Competition and a table Classement (ranking of a skier in a competition).
  We have also a fourth table called Penalise (who give us in which competition a skier has cheated).</p>
  <p>The goal of the exercise is to write a function (or more if it necessary), to put all the cheaters skier at the last rank of the competition they have cheat, and we have to update the ranking of all the other players.</p>
  <p>Here are the different table and insert:</p>
  <pre><code>CREATE TABLE skieur(
    noSkieur serial,
    nomSkieur VARCHAR,
    idSpecialite INT,
    idStation INT,
    PRIMARY KEY (noSkieur),
    CONSTRAINT fk_skieur_specialite
              FOREIGN KEY (idSpecialite) REFERENCES specialite(idSpecialite),
    CONSTRAINT fk_skieur_station
              FOREIGN KEY (idStation) REFERENCES station(idStation)
  );
  
  INSERT INTO skieur VALUES(default,'skieur1',1,1);
  INSERT INTO skieur VALUES(default,'skieur2',1,2);
  INSERT INTO skieur VALUES(default,'skieur3',2,1);
  INSERT INTO skieur VALUES(default,'skieur4',2,3);
  INSERT INTO skieur VALUES(default,'skieur5',2,1);
  INSERT INTO skieur VALUES(default,'skieur6',3,2);
  </code></pre>
  <pre><code>CREATE TABLE competition(
    idCompet serial,
    libelleCompet VARCHAR,
    dateCompet DATE,
    idStation INT,
    PRIMARY KEY (idCompet),
    CONSTRAINT fk_competition_station
              FOREIGN KEY (idStation) REFERENCES station(idStation)
  );
  
  INSERT INTO competition VALUES(default, 'compet1','2014-09-01',1);
  INSERT INTO competition VALUES(default, 'compet2','2014-09-02',1);
  INSERT INTO competition VALUES(default, 'compet3','2014-09-03',2);
  INSERT INTO competition VALUES(default, 'compet4','2014-09-04',2);
  INSERT INTO competition VALUES(default, 'compet5','2014-09-05',2);
  INSERT INTO competition VALUES(default, 'compet6','2014-09-06',3);
  </code></pre>
  <pre><code>CREATE TABLE classement(
    noSkieur INT,
    idCompet INT,
    classement INT,
    PRIMARY KEY(noSkieur, idCompet),
    CONSTRAINT fk_classement_skieur
              FOREIGN KEY (noSkieur) REFERENCES skieur(noSkieur),
    CONSTRAINT fk_classement_competition
              FOREIGN KEY (idCompet) REFERENCES competition(idCompet)
  );
  
  INSERT INTO classement VALUES(1,1,1);
  INSERT INTO classement VALUES(2,1,2);
  INSERT INTO classement VALUES(3,1,3);
  INSERT INTO classement VALUES(4,1,4);
  INSERT INTO classement VALUES(1,2,1);
  INSERT INTO classement VALUES(2,2,2);
  INSERT INTO classement VALUES(3,2,3);
  INSERT INTO classement VALUES(4,2,4);
  INSERT INTO classement VALUES(5,2,5);
  INSERT INTO classement VALUES(6,3,1);
  INSERT INTO classement VALUES(1,3,2);
  </code></pre>
  <pre><code>CREATE TABLE penalise(
    noSkieur INT,
    idCompet INT,
    PRIMARY KEY (noSkieur, idCompet),
    CONSTRAINT fk_penalise_competition
              FOREIGN KEY (idCompet) REFERENCES competition(idCompet),
    CONSTRAINT fk_penalise_skieur
              FOREIGN KEY (noSkieur) REFERENCES skieur(noSkieur)
  );
  
  INSERT INTO penalise VALUES(1, 1);
  </code></pre>
  <p>To write the function, I was thinking to this:</p>
  <p>I have a cursor on all cheaters where I iterate on.<br />
  I update the ranking of the cheater with the number of players in the competition, to put him last.<br />
  Afterwards, I call on other the decrement all the other players ranking between the position of the cheater, until the end or another cheater.</p>
  <p>Here is the code I wrote:</p>
  <pre><code>-- Decrement ranking function
  CREATE OR REPLACE FUNCTION decrement_ranking(ranking_start integer, id_competition integer)
  RETURNS integer
  AS $$
  DECLARE
    nb_modification integer := 0;
    c CURSOR FOR
      SELECT c.noSkieur, c.classement
      FROM classement AS c
      WHERE c.idCompet = id_competition AND c.classement &gt; ranking_start;
    competiter_ranking integer;  
  BEGIN
    FOR c_data IN c
      LOOP
        -- while the competiter is not a cheater
        CONTINUE WHEN c_data.noSkieur NOT IN (SELECT noSkieur FROM penalise WHERE idCompet = id_competition);
        -- get current competiter ranking
        SELECT c.classement INTO competiter_ranking
          FROM classement AS c
          WHERE c.noSkieur = c_data.noSkieur AND idCompet = id_competition;
        -- decrement ranking
        UPDATE classement
          SET classement = competiter_ranking - 1
          WHERE c.noSkieur = c_data.noSkieur AND idCompet = id_competition;
        nb_modification := nb_modification + 1;
      END LOOP;
      RETURN nb_modification;
  END;
  $$ LANGUAGE plpgsql;
  
  -- Main function
  CREATE OR REPLACE FUNCTION declasse_penalise()
  RETURNS integer
  AS $$
  DECLARE
    nb_modification integer := 0;
    c CURSOR FOR
      SELECT p.noSkieur, p.idCompet
      FROM penalise AS p;
    no_skieur_pen integer;
    id_compet_cheat integer;
    nb_competiters integer;
    ranking_cheater integer;
  BEGIN
    FOR c_data IN c
      LOOP
        no_skieur_pen := c_data.noSkieur;
        id_compet_cheat := c_data.idCompet;
  
        -- get ranking cheater
        SELECT cl.classement INTO ranking_cheater
          FROM classement AS cl
          WHERE cl.noSkieur = no_skieur_pen AND cl.idCompet = id_compet_cheat;
  
        -- put cheater in lowest ranking = number of competiters
        SELECT COUNT(sk.noSkieur) INTO nb_competiters
          FROM skieur as sk
          INNER JOIN classement AS cl ON cl.idCompet = id_compet_cheat;
  
        UPDATE classement
          SET classement = nb_competiters
          WHERE noSkieur = no_skieur_pen AND idCompet = id_compet_cheat;
  
        -- decrement all other ranking: from cheat player rank to before the next cheater (if there is one)
        nb_modification := nb_modification + decrement_ranking(ranking_cheater, id_compet_cheat);
      END LOOP;
    RETURN nb_modification;
  END;
  $$ LANGUAGE plpgsql;
  </code></pre>
  <p>Now my problem is that: my code has no compilation errors but it doesn't update as I expected.</p>
  <p>Do you have an idea why?</p>