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