Использование триггера обновления tsvector в триггере Postgres

у меня есть tsvector столбец, который я хочу обновить при изменении строки. Для INSERT Я использую этот триггер:

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

который работает нормально, по-видимому. Я хотел бы использовать другой триггер на UPDATE предложения, но я хочу, чтобы он срабатывал только при изменении имени, поэтому я не трачу циклы на обновление вектора поиска без необходимости. Я пробовал это:

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;

но это вызывает 2 ошибки, когда я пытаюсь создать триггер:

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
            ^

из моего понимание, если я использую синтаксис процедуры триггера, ala:

CREATE OR REPLACE FUNCTION something() RETURNS TRIGGER

затем свяжите мою функцию с триггером, тогда я не смогу использовать встроенный

4 ответов


Это то, что я закончил с:

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();

альтернативой может быть что-то вроде отличного от, это действительно помогло мне несколько раз. Однако непроверенный код.

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);

логика сравнения имен должна входить в код процедуры tsvector_update_trigger. что-то вроде:

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

затем создайте триггер, который вызывается перед INSERT и UPDATE


когда вы вставляете строку, вам не нужно проверять это условие, на самом деле вы не можете, так как нет старой записи:

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

обновление:

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