Триггер обновления PostgreSQL

У меня есть стол:

CREATE TABLE annotations
(
  gid serial NOT NULL,
  annotation character varying(250),
  the_geom geometry,
  "rotationAngle" character varying(3) DEFAULT 0,
  CONSTRAINT annotations_pkey PRIMARY KEY (gid),
  CONSTRAINT enforce_dims_the_geom CHECK (st_ndims(the_geom) = 2),
  CONSTRAINT enforce_srid_the_geom CHECK (st_srid(the_geom) = 4326)
)

И вызвать:

CREATE TRIGGER set_angle
AFTER INSERT OR UPDATE
ON annotations
FOR EACH ROW
EXECUTE PROCEDURE setangle();

И функция:

CREATE OR REPLACE FUNCTION setAngle() RETURNS TRIGGER AS $$
BEGIN
IF    TG_OP = 'INSERT' THEN
    UPDATE annotations SET "rotationAngle" = degrees( ST_Azimuth( ST_StartPoint(NEW.the_geom), ST_EndPoint(NEW.the_geom) ) )-90 WHERE gid = NEW.gid;
    RETURN NEW;
ELSIF TG_OP = 'UPDATE' THEN
    UPDATE annotations SET "rotationAngle" = degrees( ST_Azimuth( ST_StartPoint(NEW.the_geom), ST_EndPoint(NEW.the_geom) ) )-90 WHERE gid = NEW.gid;
    RETURN NEW;
END IF;
END;
$$ LANGUAGE plpgsql;

И когда новая строка вставлена ​​в таблицу или редактируется строка, я хочу, чтобы поле rotationAngle устанавливается с результатом функции. Но когда я вставляю новую строку в таблицу, функция не работает. Я имею ввиду rotationAngle значение не изменилось.

Что может быть не так?

2 ответа

Решение

Как отметил @SpartanElite, вы запускаете бесконечный цикл.

Упростим функцию триггера:

CREATE OR REPLACE FUNCTION set_angle()
  RETURNS TRIGGER AS
$func$
BEGIN
   NEW."rotationAngle" := degrees(
                             ST_Azimuth(
                                ST_StartPoint(NEW.the_geom)
                              , ST_EndPoint(NEW.the_geom)
                             )
                          ) - 90;
   RETURN NEW;
END
$func$ LANGUAGE plpgsql;
  • Назначить на NEW непосредственно. нет WHERE в этом случае.
  • Вы должны заключить в кавычки недопустимые имена столбцов. Лучше не использовать такие имена для начала.
    Недавний связанный ответ.
  • Код для вставки и обновления одинаков. Я сложил в один путь кода.

Использовать BEFORE спусковой крючок. Таким образом, вы можете редактировать столбцы строки запуска непосредственно перед их сохранением:

CREATE TRIGGER set_angle
BEFORE INSERT OR UPDATE ON annotations
FOR EACH ROW EXECUTE PROCEDURE set_angle();

тем не мение

Если вы просто пытаетесь сохранить функционально зависимое значение в таблице (а других соображений нет): не делайте этого. Вместо этого используйте представление или сгенерированный столбец:

Тогда тебе это не нужно.

Здесь несколько вещей не так. 1) При вставке строки "А" функция setAngle() называется. Но в функции вы вызываете другой update внутри функции, которая будет вызывать функцию снова, и снова, и так далее... Чтобы исправить это, не выпускайте обновление! Просто обновите значение новых записей независимо и верните его.

Другие вопросы по тегам