проблема с триггером

vavcgcg
Дата: 24.08.2004 15:55:54
Есть таблица :

CREATE TABLE public.an_obz (
id int4 DEFAULT nextval('"an_obz_id_seq"'::text) NOT NULL,
date char(14),
url text,
title text,
text text,
type int4,
source char(512),
status int4 DEFAULT 0,
indexed int2 DEFAULT 0,
CONSTRAINT an_obz_pkey PRIMARY KEY (id)
) WITH OIDS;

В ней есть записи.

Создаю функцию :

CREATE or replace FUNCTION public.vav_update_an_obz() RETURNS trigger AS 'begin
update an_obz set indexed = 0 where id = old.id;
end;' LANGUAGE 'plpgsql' STABLE;

Создаю триггер :

CREATE TRIGGER up_an_obz AFTER UPDATE ON public.an_obz FOR EACH ROW EXECUTE PROCEDURE vav_update_an_obz();

Т.е. хочу, чтобы при изменении записи в таблице an_obz , значение
поля indexed этой записи становилось равным 0...

Делаю запрос :

update an_obz set text = 'qwewewe' where id = 5;

Получаю ошибку :

2004-08-24 15:47:40 [32003] ERROR: control reached end of trigger procedure without RETURN
CONTEXT: PL/pgSQL function "vav_update_an_obz"

Где собака зарыта ???
assa
Дата: 24.08.2004 16:47:34
Собака в необходимости
RETURN (что-нито) в теле ф-ии. (напр: ... RETURN OLD; END;)

например, для вашего случая:
CREATE or replace FUNCTION public.vav_update_an_obz() RETURNS trigger AS '
DECLARE
begin
%af_src_comm_0
NEW.indexed :=0;
Return NEW;
end;' LANGUAGE 'plpgsql' STABLE;
автор

DROP TRIGGER up_an_obz ON public.an_obz;
CREATE TRIGGER up_an_obz BEFORE UPDATE ON public.an_obz FOR EACH ROW EXECUTE PROCEDURE vav_update_an_obz();

(А иначе на бесконечный цикл смахивает )
assa
Дата: 24.08.2004 16:52:15
автор
CREATE or replace FUNCTION public.vav_update_an_obz() RETURNS trigger AS '
DECLARE
begin
/* update an_obz set indexed = 0 where id = old.id; */
NEW.indexed :=0;
Return NEW;
end;' LANGUAGE 'plpgsql' STABLE;


былин, форматировщик кода глотает /* ... */ внутри строки
vavcgcg
Дата: 24.08.2004 17:01:51
Работает !
Делает то, что нужно !
Спасибо !
Я обожаю триггеры :)
vavcgcg
Дата: 24.08.2004 17:03:31
Работает !
Делает то, что нужно !
Спасибо !
Я обожаю триггеры :)
ss25
Дата: 21.09.2009 16:52:35
Такая же проблема на PG 8.4.0 на FreeBSD
если без тригера то вставка проходит иначе ошибка

2009-09-21 15:49:36 UTC - [pgsql:abis] - LOG:  duration: 0.174 ms  parse pdo_pgsql_stmt_0a62893c: SELECT library.inv_add($1, $2, $3, $4)
2009-09-21 15:49:36 UTC - [pgsql:abis] - LOG:  duration: 0.037 ms  bind pdo_pgsql_stmt_0a62893c: SELECT library.inv_add($1, $2, $3, $4)
2009-09-21 15:49:36 UTC - [pgsql:abis] - DETAIL:  parameters: $1 = '31', $2 = '4578', $3 = '123', $4 = '25'
2009-09-21 15:49:36 UTC - [pgsql:abis] - ERROR:  control reached end of trigger procedure without RETURN
2009-09-21 15:49:36 UTC - [pgsql:abis] - CONTEXT:  PL/pgSQL function "trg_a_ins_upd_del_inv_add"
        SQL statement "INSERT INTO library.books_inv (book_id, price, inv) VALUES ( $1 ,  $2 ,  $3 )"
        PL/pgSQL function "inv_add" line 17 at SQL statement
2009-09-21 15:49:36 UTC - [pgsql:abis] - STATEMENT:  SELECT library.inv_add($1, $2, $3, $4)

Функция вставки
CREATE OR REPLACE FUNCTION "library"."inv_add" (integer, integer, integer, numeric) RETURNS boolean AS 'DECLARE

_book_id       INT4;
_price         NUMERIC(20,2);
_cnt           INT4;
_inv           INT4;
_i             INT4;
BEGIN

_book_id    := $1;
_inv        := $2;
_cnt        := $3;
_price      := $4;
_i          := 0;

WHILE (_i < _cnt) LOOP
     INSERT INTO library.books_inv (book_id, price, inv) VALUES (_book_id, _price, _inv);
     _inv := _inv + 1;
     _i := _i + 1;
END LOOP;

RETURN TRUE;
END;' LANGUAGE "plpgsql" COST 100
VOLATILE
CALLED ON NULL INPUT
SECURITY INVOKER

Тригер
CREATE OR REPLACE FUNCTION "library"."trg_a_ins_upd_del_inv_add" () RETURNS trigger AS 'BEGIN
IF (TG_OP != ''INSERT'') THEN
--    UPDATE library.books SET 
--                  cnt_inv = cnt_inv + 1, 
--                  cnt_nal = cnt_nal + 1,
--                  sum_inv = sum_inv + NEW.price,
--                  sum_nal = sum_nal + NEW.price,
--                  last_add = NOW()::date 
--          WHERE id = NEW.book_id;
    RETURN NEW;
ELSIF (TG_OP = ''UPDATE'') THEN
--    UPDATE library.books SET 
--                  sum_inv = sum_inv + NEW.price - OLD.price,
--                  sum_nal = sum_nal + NEW.price - OLD.price,
--                  last_add = NEW.data::date 
--          WHERE id = NEW.book_id;
    RETURN NEW;
ELSIF (TG_OP = ''DELETE'') THEN
--    UPDATE library.books SET 
--                  cnt_inv = cnt_inv - 1, 
--                  cnt_nal = cnt_nal - 1,
--                  sum_inv = sum_inv - OLD.price,
--                  sum_nal = sum_nal - OLD.price,
--                  last_add = NOW()::date 
--          WHERE id = OLD.book_id;
    RETURN OLD;
END IF;
END;' LANGUAGE "plpgsql" COST 100
VOLATILE
CALLED ON NULL INPUT
SECURITY INVOKER

Warstone
Дата: 21.09.2009 17:13:33
Ну прально... Попробуйте в TG_OP засунуть INSERT и покажите мне где происходит RETURN в триггере?
ss25
Дата: 21.09.2009 17:19:05
ну там же в теле написано RETURN NEW; после закоментированного запроса

Со всеми разговариваю уважительно, но недолго. На вопросы типа ...Как дела? ...не отвечаю, это флуд.
© Lister the Tormentor
ss25
Дата: 21.09.2009 17:20:59
2009-09-21 16:18:52 UTC - [pgsql:abis] - STATEMENT:  SELECT library.inv_add(31,4578,123,25);
2009-09-21 16:19:21 UTC - [pgsql:abis] - ERROR:  control reached end of trigger procedure without RETURN
2009-09-21 16:19:21 UTC - [pgsql:abis] - CONTEXT:  PL/pgSQL function "trg_a_ins_upd_del_inv_add"
2009-09-21 16:19:21 UTC - [pgsql:abis] - STATEMENT:  INSERT INTO library.books_inv (book_id, price, inv) VALUES (31,4578,23);
Со всеми разговариваю уважительно, но недолго. На вопросы типа ...Как дела? ...не отвечаю, это флуд.
© Lister the Tormentor
Warstone
Дата: 21.09.2009 17:21:57
[FIX]IF (TG_OP != ''INSERT'') THEN[/FIX]
Это значит что если TG_OP НЕ INSERT то NEW, а если INSERT? То он ни в одну ветку не попадает и вываливается в конец триггера, где RETURN'а нет. О чем и радостно сообщает.