2017-06-24 3 views
0

Ich frage mich, ob es etwas in Zusammenhang mit Variablen und verschachtelten Schleifen in PostgreSQL gibt, die anders als in anderen Sprachen funktioniert.Problem mit verschachtelten Schleifen in Postgresql

Beispiel:

CREATE OR REPLACE FUNCTION public.generate_syllables() 
    RETURNS integer AS 
$BODY$ 

DECLARE 
w RECORD; 
s RECORD; 
current_syllable integer := 1; 
vowel_trigger integer := 0; 
syllable_count integer := 1; 

BEGIN 

FOR w IN SELECT id FROM words LOOP 
    FOR s IN SELECT sound, id FROM sounds WHERE id = w.id ORDER BY ordering LOOP 
     IF (SELECT sr.vowel FROM sound_reference sr WHERE sr.sound = s.sound) = 1 AND vowel_trigger = 1 THEN 
      syllable_count := syllable_count + 1; 
      UPDATE sounds SET syllable = syllable_count WHERE id = s.id; 
      vowel_trigger := 0; 
     ELSIF (SELECT sr.vowel FROM sound_reference sr WHERE sr.sound = s.sound) = 1 THEN 
      vowel_trigger := 1; 
      UPDATE sounds SET syllable = syllable_count WHERE id = s.id; 
     ELSE 
      UPDATE sounds SET syllable = syllable_count WHERE id = s.id; 
     END IF; 
    END LOOP; 
    UPDATE words SET syllables = syllable_count WHERE id = w.id; 
    syllable_count := 1; 
    vowel_trigger := 0; 

END LOOP; 

RETURN 1; 

END; 

$BODY$ 
    LANGUAGE plpgsql VOLATILE 

Wenn ich diese Funktion ausführen wie es ist, die Funktion tritt nie die erste Bedingung in der if-Anweisung. Ich habe dies getestet, indem ich eine Return-Anweisung innerhalb dieser ersten Bedingung hinzugefügt habe. Zuerst dachte ich, dass dies ein logischer Fehler sein muss, aber ich habe es manuell mit Beispielen durchsucht, die aus meinem Datensatz generiert wurden, und es sollte wie gewünscht funktionieren. Was noch seltsamer ist, ist, wenn ich die Zeile in der äußeren Schleife auszeichne, für vowel_trigger: = 0, dann gibt es die erste if-Anweisung ein. Natürlich funktioniert auch die Logik nicht korrekt, und daraus entnehme ich, dass silbyl_count auf 0 zurückgesetzt wird, BEVOR die verschachtelte Schleife die Schleife beendet, was auch erklären würde, warum die erste Bedingung nie eingegeben wird, weil vowel_trigger gesetzt ist zurück zu 0, bevor die Schleife wieder in den ersten Zustand zurückkehrt.

Mit anderen Worten, es scheint mir, dass meine verschachtelte Schleife nicht wie eine verschachtelte Schleife, sondern eher die verschachtelte Schleife in die äußere Schleife vor dem Neustart der verschachtelten Schleife. Ich stelle mir vor, ich muss einfach nicht verstehen, wie man eine verschachtelte Schleife richtig erstellt, oder vielleicht können sie einfach nicht so in POSTGRESQL arbeiten ... jeder Rat würde sehr geschätzt werden.

Antwort

0

Sie haben keine Tabellenstrukturen und - noch wichtiger - Daten bereitgestellt. Das Verhalten Ihrer Funktion hängt von den Daten in den Tabellen words, sounds und sound_reference ab. Zum Beispiel, wenn sound_reference ist leer, vowel_trigger wird nie 1, so dass die erste IF wird nicht erreichbar.

Dies wird helfen, Ihre Funktion zu debuggen:

RAISE NOTICE 'printlining helps to debug! vowel_trigger=%, syllable_count=%', 
    vowel_trigger, syllable_count; 

Als Randbemerkung, ich habe bemerkt, dass UPDATE sounds SET syllable = syllable_count WHERE id = s.id; in allem, wenn/sonst Fällen wiederholt wird, so kann es sein, lohnt sich außerhalb, sie zu bewegen und Platzieren Sie direkt vor dem inneren END LOOP;.

Zusatz:

... wenn ich die Zeile in der äußeren Schleife auf Kommentar, für vowel_trigger: = 0, dann ist es geben Sie die erste if-Anweisung.

Es sagt uns, dass einer der inneren Schleife der Hinrichtungen endet mit vowel_trigger 1 zu sein, und es wäre der erste IF auslösen, erlauben aber direkt vor der inneren Schleife Sie es 0 drehen, so dass die erste IF nicht der Fall ist arbeite dann.

Verwandte Themen