Использование триггера обновления 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



Затем свяжите мою функцию с триггером, тогда я не смогу использовать встроенную функцию tsvector_update_trigger и мне нужно будет самому справиться с манипуляцией ts_vector. Поэтому я пытаюсь использовать синтаксис all-in-one-trigger+procedure...



Есть идеи?

780   4  

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

Comments

    Ничего не найдено.