2017-11-28 1 views
0

Ich versuche, ein deklariertes Array von allen Hunden, die die gleiche family_id teilen, zu erstellen und die Tabelle dog_characteristics mit dem Array abzufragen.Wie rufe ich eine deklarierte Array-Variable in einer Where-Klausel in Postgres auf?

CREATE OR REPLACE FUNCTION update_dog_characteristics_guarantor_id() 
    RETURNS trigger AS $$ 
    DECLARE dog_ids INT[]; 

    BEGIN 
    SELECT id into dog_ids FROM dogs WHERE dogs.family_id = OLD.id; 
    IF ((OLD.family_id IS NOT NULL) && ((SELECT COUNT(*) FROM dog_ids) > 0)) THEN 
     UPDATE 
     dog_characteristics 
     SET 
     guarantor_id = NEW.guarantor_id 
     WHERE 
     dog_characteristics.account_id = OLD.account_id 
     AND dog_characteristics.dog_id IN ANY(dog_ids); 
     RETURN NULL; 
    END IF; 
    RETURN NULL; 
    END; 
$$ LANGUAGE plpgsql; 

Was ich

AND dog_characteristics.dog_id = ANY(dog_ids); 
AND dog_characteristics.dog_id = ANY(dog_ids::int[]); 
AND dog_characteristics.dog_id IN (dog_ids::int[]); 
AND dog_characteristics.dog_id IN (dog_ids); 
AND dog_characteristics.dog_id IN (ARRAY(dog_ids)); 
AND dog_characteristics.dog_id IN ARRAY(dog_ids); 
AND dog_characteristics.dog_id IN implode(',', dog_ids); 

Die häufigsten Fehler

ERROR: malformed array literal: "672" 
    DETAIL: Array value must start with "{" or dimension information. 
    CONTEXT: PL/pgSQL function update_dog_characteristics_guarantor_id() line 5 at SQL statement 
+1

'= ANY (dog_ids); 'sollte funktionieren –

+0

Das gibt mir den Fehler über das fehlerhafte Array-Literal. Liegt es daran, dass es nur eine ID zurückgibt? –

+0

Ich versuchte = dog_ids und das schlägt mit dem gleichen Fehler fehl. –

Antwort

1

Es gibt mehrere Fehler in der Trigger-Funktion versucht haben.

Da als Array deklariert ist, muss das Ergebnis der ersten Auswahl ebenfalls ein Array sein. Dazu müssen Sie alle IDs aggregieren, die von der Abfrage zurückgegeben werden.

So ist die erste select-Anweisung

select array_agg(id) --<< aggregate all IDs into an array 
    into dog_ids 
FROM dogs 
WHERE dogs.family_id = OLD.id; 

Um zu überprüfen, ob ein Array-Elemente sein sollte hat, kann man nicht select count(*) verwenden können, müssen Sie die Verwendung array_length() oder cardinality() verwenden.

Die && ist nicht die "AND" Operator in SQL - das ist AND - so sein das if sollte:

IF OLD.family_id IS NOT NULL AND cardinality(dog_ids) > 0 THEN 
    ... 
END IF; 

Die where Bedingung auf dem Array sein sollte:

AND dog_characteristics.dog_id = ANY(dog_ids); 
Verwandte Themen