Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Триггерная функция / 12 сообщений из 12, страница 1 из 1
28.12.2006, 12:31
    #34230142
postuser
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Триггерная функция
Есть триггерная функция:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
CREATE OR REPLACE FUNCTION funct_trigger()
RETURNS "trigger" AS
$BODY$
begin
UPDATE table1 SET p1=p1+new.p2 WHERE table1.id=(SELECT id FROM table2 WHERE table2.id=new.p3);
RETURN NEW;
end;
$BODY$
LANGUAGE 'plpgsql' VOLATILE;
Требуется каким-то образом проверить, успешно ли прошло обновление. И если не успешно (не выполнено условие WHERE), то должен делаться INSERT table1 (id) VALUES (new.p3). Как это сделать?В EXCEPTION WHEN что-то THEN не нашел, какое условие прописать после when.
А вообще хотелось бы на Си функцию написать, только не могу разобраться с этим, привык libpq использовать.
...
Рейтинг: 0 / 0
28.12.2006, 14:09
    #34230503
Kruchinin Pahan
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Триггерная функция
postuserТребуется каким-то образом проверить, успешно ли прошло обновление. И если не успешно (не выполнено условие WHERE), то должен делаться INSERT table1 (id) VALUES (new.p3). Как это сделать?В EXCEPTION WHEN что-то THEN не нашел, какое условие прописать после when.
А вообще хотелось бы на Си функцию написать, только не могу разобраться с этим, привык libpq использовать.
А почему не использовать
IF NOT FOUND THEN
INSERT ...
END IF ;
...
Рейтинг: 0 / 0
28.12.2006, 14:22
    #34230562
postuser
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Триггерная функция
Пробывал уже, срабатывает в любом случае (хоть UPDATE прошел, хоть нет). Как я понял, это для SELECT.
...
Рейтинг: 0 / 0
28.12.2006, 14:26
    #34230582
postuser
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Триггерная функция
Если вставляю после UPDATE
Код: plaintext
1.
2.
3.
4.
SELECT id FROM table2 WHERE table2.id=new.p3;
IF NOT FOUND THEN
 INSERT INTO ....;
END IF;
то выдает ошибку
Код: plaintext
1.
2.
ERROR:  query has no destination for result data
HINT:  If you want to discard the results of a SELECT, use PERFORM instead.
CONTEXT:  PL/pgSQL function "funct_trigger" line  4  at SQL statement
...
Рейтинг: 0 / 0
28.12.2006, 14:42
    #34230646
Kruchinin Pahan
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Триггерная функция
Может так?
Код: plaintext
1.
2.
3.
4.
5.
6.
DECLARE AnyRow RECORD ;

SELECT INTO AnyRow id FROM table2 WHERE table2.id=new.p3;
IF NOT FOUND THEN
 INSERT INTO ....;
END IF;
А вообще, странно... Обычно FOUND и на UPDATE отрабатывает... Может это от версии зависит или от настроек. У меня работает с 7.4 начиная.
...
Рейтинг: 0 / 0
28.12.2006, 14:44
    #34230651
Kruchinin Pahan
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Триггерная функция
postuserПробывал уже, срабатывает в любом случае (хоть UPDATE прошел, хоть нет). Как я понял, это для SELECT.
Покажи DDL самого триггера.
...
Рейтинг: 0 / 0
28.12.2006, 15:00
    #34230702
postuser
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Триггерная функция
Сам триггер:
Код: plaintext
1.
2.
3.
4.
CREATE TRIGGER tg
AFTER INSERT
ON table3
FOR EACH ROW
EXECUTE PROCEDURE funct_trigger();
...
Рейтинг: 0 / 0
28.12.2006, 15:09
    #34230727
4321
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Триггерная функция
postuserПробывал уже, срабатывает в любом случае (хоть UPDATE прошел, хоть нет). Как я понял, это для SELECT.странные вещи вы расказываете, однако. могабыть что-то не то пробовали?

я с перепугу даже доку перечитал - все на месте
докаThe second method to determine the effects of a command is to check the special variable named FOUND, which is of type boolean. FOUND starts out false within each PL/pgSQL function call. It is set by each of the following types of statements:

A SELECT INTO statement sets FOUND true if it returns a row, false if no row is returned.

A PERFORM statement sets FOUND true if it produces (and discards) a row, false if no row is produced.

UPDATE, INSERT, and DELETE statements set FOUND true if at least one row is affected, false if no row is affected.

A FETCH statement sets FOUND true if it returns a row, false if no row is returned.

A FOR statement sets FOUND true if it iterates one or more times, else false. This applies to all three variants of the FOR statement (integer FOR loops, record-set FOR loops, and dynamic record-set FOR loops). FOUND is set this way when the FOR loop exits; inside the execution of the loop, FOUND is not modified by the FOR statement, although it may be changed by the execution of other statements within the loop body.

FOUND is a local variable within each PL/pgSQL function; any changes to it affect only the current function.
"Ниччего не понимаю" (с)
...
Рейтинг: 0 / 0
28.12.2006, 15:19
    #34230771
4321
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Триггерная функция
а рекомендованный разработчиками метод ведения итогов (исключительно в умолчательном режиме READ COMMITED) рассматривался надысь здесь: вот оно .


случай просто с FOUND приведет к отлупу (если проектировали не левой задней, и есть ключ в накопит. табличке) в том редком случае, когда конкурент успеет вставить свою запись промеж вашей попыки апдейта, и инсерта в триггере
...
Рейтинг: 0 / 0
28.12.2006, 17:08
    #34231111
Jelis
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Триггерная функция
postuserЕсли вставляю после UPDATE
Код: plaintext
1.
2.
3.
4.
SELECT id FROM table2 WHERE table2.id=new.p3;
IF NOT FOUND THEN
 INSERT INTO ....;
END IF;
то выдает ошибку
Код: plaintext
1.
2.
ERROR:  query has no destination for result data
HINT:  If you want to discard the results of a SELECT, use PERFORM instead.
CONTEXT:  PL/pgSQL function "funct_trigger" line  4  at SQL statement


ПОДСКАЗКА: Если вам результат СЕЛЕКТА нафик не сдался, то используйте PERFORM.
Вот таким образом :
Код: plaintext
1.
2.
3.
4.
PERFORM SELECT id FROM table2 WHERE table2.id=new.p3;
IF NOT FOUND THEN
 INSERT INTO ....;
END IF;
...
Рейтинг: 0 / 0
29.12.2006, 16:24
    #34233057
Andrey Daeron
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Триггерная функция
4321
случай просто с FOUND приведет к отлупу (если проектировали не левой задней, и есть ключ в накопит. табличке) в том редком случае, когда конкурент успеет вставить свою запись промеж вашей попыки апдейта, и инсерта в триггере
Есть неплохая идея для таких целей лочить табличку на запись. "Во избежание".
...
Рейтинг: 0 / 0
29.12.2006, 17:19
    #34233202
Jelis
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Триггерная функция
Andrey Daeron 4321
случай просто с FOUND приведет к отлупу (если проектировали не левой задней, и есть ключ в накопит. табличке) в том редком случае, когда конкурент успеет вставить свою запись промеж вашей попыки апдейта, и инсерта в триггере
Есть неплохая идея для таких целей лочить табличку на запись. "Во избежание".
Лочить табличку хороший метод решающий большенство подобных проблемм (а то и все), но, за счет понижения производительности. Если данный код выполняеться не часто, и не так критичен для производительности, то все ок. Но, imho, способ с обработкой эксепшенса более производителен (опятьтакиже, как в той ссылке, что дал 4321).
...
Рейтинг: 0 / 0
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Триггерная функция / 12 сообщений из 12, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]