# triggerfunction funzt nicht



## noisebreath (30. Jan 2009)

hi hab ne triggerfunction geschrieben, aber die funzt nicht. Vielleicht sieht ja jemand von euch woran es liegt:


```
CREATE OR REPLACE FUNCTION calculateoverallscore() RETURNS TRIGGER AS $testswherechanged$
DECLARE
	totalscore numeric;

BEGIN
	IF (OLD.testid != 8)
				
		IF(SELECT COUNT(*) FROM resultsview WHERE testperiodid = OLD.testperiodid AND talentid=OLD.talentid AND testid in ('2','3','4','5','7') = 5) THEN

			FOR values IN (SELECT testid, value FROM results WHERE testperiodid = OLD.testperiodid AND talentid = OLD.talentid ORDER BY testid ASC) LOOP
				IF(values.testid = 2) THEN
				totalscore := values.value * 17.29
				END IF;
				IF(values.testid = 3) THEN
				totalscore := totalscore + values.value * 9.43
				END IF;
				IF(values.testid = 4) THEN
				totalscore := totalscore + values.value * 4.11
				END IF;
				IF(values.testid = 5) THEN
				totalscore := totalscore + values.value * 2.41
				END IF;
				IF(values.testid = 7) THEN
				totalscore := totalscore + values.value,
				END IF;
					
					
			END LOOP;
			
			totalscore := 1/totalscore*10000
			INSERT INTO results (value,testid,testperiodid,talentid,changed,created) VALUES(totalscore,8,OLD.testperiodid,OLD.talentid,current_timestamp,current_timestamp);

		END IF;
		
	END IF;
END;
$testswherechanged$ LANGUAGE plpgsql;
CREATE TRIGGER testswherechanged AFTER INSERT ON results FOR EACH ROW EXECUTE PROCEDURE calculateoverallscore();
```

Fehlermeldung beim ausführen:

ERROR:  syntax error at or near "IF"
LINE 1: SELECT  ( $1  != 8) IF(SELECT COUNT(*) FROM resultsview WHER...
                            ^
QUERY:  SELECT  ( $1  != 8) IF(SELECT COUNT(*) FROM resultsview WHERE testperiodid =  $2  AND talentid= $3  AND testid in ('2','3','4','5','7') = 5)
CONTEXT:  SQL statement in PL/PgSQL function "calculateoverallscore" near line 7

********** Fehler **********

ERROR: syntax error at or near "IF"
SQL Status:42601

bitte um hilfe


----------



## SlaterB (30. Jan 2009)

zu einem IF gehört doch immer noch ein THEN? zwischen den beiden IF in Zeile 7 bis 9 ist keines

warum so kompliziert aber die einfachste Grundsyntax noch nicht korrekt 

immer möglichst einfach anfangen oder zumindest wenn ein Fehler kommt,
dann erstmal alles unnötige raus und

IF true THEN
hello world

oder ähnlich testen, 
von PL SQL weiß ich nix


----------



## noisebreath (30. Jan 2009)

danke dass hab ich übersehen ^^

jetzt passt das aber er schmeisst mir eine weitere meldung :


ERROR:  loop variable of loop over rows must be a record or row variable or list of scalar variables at or near "LOOP"
LINE 13: ...riodid AND talentid = OLD.talentid ORDER BY testid ASC) LOOP
                                                                    ^

********** Fehler **********

ERROR: loop variable of loop over rows must be a record or row variable or list of scalar variables at or near "LOOP"
SQL Status:42601
Zeichen:450


----------



## noisebreath (30. Jan 2009)

hab übrigens rausgefunden dass bei inserts die variablen nicht old. sind sondern dann mit new. angesprochen werden muessen:


```
CREATE OR REPLACE FUNCTION calculateoverallscore() RETURNS TRIGGER AS $testswherechanged$
DECLARE
	totalscore numeric;

BEGIN
	IF (new.testid != 8) THEN
				
		IF(SELECT COUNT(*) FROM resultsview WHERE testperiodid = new.testperiodid AND talentid=new.talentid AND testid in ('2','3','4','5','7') = 5) THEN

			FOR values IN (SELECT testid, value FROM results WHERE testperiodid = new.testperiodid AND talentid = new.talentid ORDER BY testid ASC) LOOP
				IF(values.testid = 2) THEN
				totalscore := values.value * 17.29
				END IF;
				IF(values.testid = 3) THEN
				totalscore := totalscore + values.value * 9.43
				END IF;
				IF(values.testid = 4) THEN
				totalscore := totalscore + values.value * 4.11
				END IF;
				IF(values.testid = 5) THEN
				totalscore := totalscore + values.value * 2.41
				END IF;
				IF(values.testid = 7) THEN
				totalscore := totalscore + values.value,
				END IF;
					
					
			END LOOP;
			
			totalscore := 1/totalscore*10000
			INSERT INTO results (value,testid,testperiodid,talentid,changed,created) VALUES(totalscore,8,new.testperiodid,new.talentid,current_timestamp,current_timestamp);

		END IF;
		
	END IF;
END;
$testswherechanged$ LANGUAGE plpgsql;
CREATE TRIGGER testswherechanged AFTER INSERT ON results FOR EACH ROW EXECUTE PROCEDURE calculateoverallscore();
```

aber was die fehlermeldung anbelangt hat sich leider nichts geändert :-/ hab ich was bei der loopsyntax falsch verstanden?


----------



## SlaterB (30. Jan 2009)

kann es sein, dass VALUES gerade ein Schlüsselwort in SQL ist? Groß/ Kleinschreibung muss ja niemanden beeindrucken,
versuche bitte einen der 10^30 anderen möglichen Variablennamen


----------



## noisebreath (30. Jan 2009)

vollkommen korrekt:


```
DECLARE
 totalscore numeric;
 currentrow RECORD;
 counter INTEGER;
 
BEGIN
 IF (NEW.testid != 8) THEN
    SELECT INTO counter COUNT(*) FROM resultsview WHERE testperiodid = NEW.testperiodid AND talentid=NEW.talentid AND testid in ('2','3','4','5','7');
  IF(counter = 5) THEN
 
   FOR currentrow IN (SELECT testid, value FROM results WHERE testperiodid = NEW.testperiodid AND talentid = NEW.talentid ORDER BY testid ASC) LOOP
    IF(currentrow.testid = 2) THEN
     totalscore := currentrow.value * 17.29;
    ELSEIF(currentrow.testid = 3) THEN
     totalscore := totalscore + currentrow.value * 9.43;
    ELSEIF(currentrow.testid = 4) THEN
     totalscore := totalscore + currentrow.value * 4.11;
    ELSEIF(currentrow.testid = 5) THEN
     totalscore := totalscore + currentrow.value * 2.41;
    ELSEIF(currentrow.testid = 7) THEN
     totalscore := totalscore + currentrow.value;
    END IF;
   END LOOP;
   
   totalscore := 1/totalscore*10000;
   INSERT INTO results (value,testid,testperiodid,talentid,changed,created) VALUES (totalscore,8,NEW.testperiodid,NEW.talentid,current_timestamp,current_timestamp);
   RETURN NULL;
  ELSE
   RETURN NULL;
  END IF;
 ELSE
  RETURN NULL;
 END IF;
 
END;
```


----------

