после миграции с сервера PostgreSQL версии 9 на 8.4 Я столкнулся с очень странной ошибкой.Триггер PostgreSQL вызывает ошибку 55000
Краткое описание:
Если есть триггер на данной таблице для каждой строки перед тем вставки или обновления и один использует в условном операторе (если-то еще) Контрольное значение TG_OP и OLD объект, следующий ошибка возникает, когда doinng ВСТАВКУ:
ERROR: record "old" is not assigned yet
DETAIL: The tuple structure of a not-yet-assigned record is indeterminate.
Подробное описание:
Существует следующая структура БД:
CREATE TABLE table1
(
id serial NOT NULL,
name character varying(256),
CONSTRAINT table1_pkey PRIMARY KEY (id)
)
WITH (OIDS=FALSE);
CREATE OR REPLACE FUNCTION exemplary_function()
RETURNS trigger AS
$BODY$ BEGIN
IF TG_OP = 'INSERT' OR OLD.name <> NEW.name THEN
NEW.name = 'someName';
END IF;
RETURN NEW;
END;
$BODY$
LANGUAGE plpgsql VOLATILE COST 100;
CREATE TRIGGER trigger1
BEFORE INSERT OR UPDATE
ON table1
FOR EACH ROW EXECUTE PROCEDURE exemplary_function();
и после SQL-запрос, который вызывает ошибку:
INSERT INTO table1 (name) VALUES ('other name')
Похоже, анализатор не останавливается на TG_OP = 'INSERT'
состоянии (и это должно, потому что это правда), но проверяет другую и вызывает ошибку. Что интересно, я смог воспроизвести его только на версии 8.4.
OLD не существует для инструкций INSERT. (Вы уже это знали, другие, посетившие здесь, не могли). Для тестирования может потребоваться переписать, чтобы сделать отдельные условные инструкции 'TG_OP = 'INSERT' и' OLD.name <> NEW.name'. То есть, переместите 'OLD.name <> NEW.name' в предложение ELSE или в предложение ELSEIF. –
@ MikeSherrill'Catcall ', вы правы, но в этом все дело. Ввод его в отдельные условности делает работу, но дело в том, чтобы все это было в одном. В реальном живом примере я сделал это как временное решение, но мне пришлось скопировать весь блок кода ... – Wiktor
Если это сработало, мой следующий тест может заключаться в том, чтобы добавить parens, чтобы гарантировать правильный приоритет: 'IF (TG_OP = 'INSERT ') ИЛИ (OLD.name <> NEW.name) THEN'. Сказав это, я не знаю о приоритетных ошибках в 8.4, но раньше я не знал о таких вещах. –