2011-07-21 10 views
5

Mam kolumnę tsvector, którą chcę zaktualizować po zmianie wiersza. Dla INSERT Używam tego wyzwalania:Używanie wyzwalacza aktualizacji tsvector w wyzwalaczu Postgres wyzwala

CREATE TRIGGER albums_vector_insert BEFORE INSERT 
ON albums 
FOR EACH ROW EXECUTE PROCEDURE 
tsvector_update_trigger('search_vector', 'pg_catalog.english', 'name') 

który działa dobrze, pozornie. Chciałbym użyć innego wyzwalacza na klauzulach UPDATE, ale chcę, aby był uruchamiany tylko wtedy, gdy nazwa rzeczywiście się zmienia, więc nie marnuję cykli aktualizowania wektora wyszukiwania niepotrzebnie. Próbowałem to:

CREATE TRIGGER albums_vector_update BEFORE UPDATE ON albums 
FOR EACH ROW EXECUTE PROCEDURE 
    IF NEW.name <> OLD.name THEN 
     tsvector_update_trigger(search_vector, 'pg_catalog.english', name); 
    END IF; 

Ale to rzuca 2 błędy podczas próby utworzenia spust:

Error : ERROR: syntax error at or near "NEW" 
LINE 3: IF NEW.name <> OLD.name THEN 
      ^
Error : ERROR: syntax error at or near "IF" 
LINE 1: END IF 
      ^

Z mojego zrozumienia, jeśli mogę użyć składni procedura wyzwalania, Ala:

CREATE OR REPLACE FUNCTION something() RETURNS TRIGGER

następnie skojarz moją funkcję z wyzwalaczem, wtedy nie będę mógł korzystać z wbudowanej funkcji tsvector_update_trigger i będę musiał obsługiwać ts_vector samemu. Stąd moje próby użycia składni procedury all-in-one-trigger + ...

Jakieś pomysły?

Odpowiedz

12

To, co skończyło się z:

CREATE FUNCTION albums_vector_update() RETURNS TRIGGER AS $$ 
BEGIN 
    IF TG_OP = 'INSERT' THEN 
     new.search_vector = to_tsvector('pg_catalog.english', COALESCE(NEW.name, '')); 
    END IF; 
    IF TG_OP = 'UPDATE' THEN 
     IF NEW.name <> OLD.name THEN 
      new.search_vector = to_tsvector('pg_catalog.english', COALESCE(NEW.name, '')); 
     END IF; 
    END IF; 
    RETURN NEW; 
END 
$$ LANGUAGE 'plpgsql'; 


CREATE TRIGGER tsvectorupdate BEFORE INSERT OR UPDATE ON albums 
FOR EACH ROW EXECUTE PROCEDURE albums_vector_update(); 
+0

Występuje literówka w kodzie. Powinieneś mieć wyzwalacz PRZED WSTAWIĆ LUB AKTUALIZACJĄ, ponieważ NOWY jest ignorowany w przypadku wyzwalaczy AFTER. –

+0

@omatrot tak masz rację! Naprawiłem - dzięki za napiwek. –

0

Logika porównywania nazw musi znaleźć się w kodzie procedury tsvector_update_trigger. coś takiego:

IF TG_OP = 'UPDATE' THEN 
    IF NEW.name <> OLD.name THEN 
     -- Do tsvector update 
    END IF; 
END IF; 

Następnie należy utworzyć wyzwalacz, która jest wywoływana przed INSERT i UPDATE

2

Alternatywą może być coś w odróżnieniu od, to naprawdę pomogło mi kilka razy. Nie przetestowany kod.

CREATE TRIGGER albums_vector_update 
BEFORE INSERT OR UPDATE ON albums 
FOR EACH ROW 
WHEN (OLD.name IS DISTINCT FROM NEW.name) 
EXECUTE PROCEDURE tsvector_update_trigger(search_vector, 'pg_catalog.english', NEW.name); 
Powiązane problemy