powered by simpleCommunicator - 2.0.60     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Триггерная функция
12 сообщений из 12, страница 1 из 1
Триггерная функция
    #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
Триггерная функция
    #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
Триггерная функция
    #34230562
postuser
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Пробывал уже, срабатывает в любом случае (хоть UPDATE прошел, хоть нет). Как я понял, это для SELECT.
...
Рейтинг: 0 / 0
Триггерная функция
    #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
Триггерная функция
    #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
Триггерная функция
    #34230651
Kruchinin Pahan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
postuserПробывал уже, срабатывает в любом случае (хоть UPDATE прошел, хоть нет). Как я понял, это для SELECT.
Покажи DDL самого триггера.
...
Рейтинг: 0 / 0
Триггерная функция
    #34230702
postuser
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сам триггер:
Код: plaintext
1.
2.
3.
4.
CREATE TRIGGER tg
AFTER INSERT
ON table3
FOR EACH ROW
EXECUTE PROCEDURE funct_trigger();
...
Рейтинг: 0 / 0
Триггерная функция
    #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
Триггерная функция
    #34230771
4321
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
а рекомендованный разработчиками метод ведения итогов (исключительно в умолчательном режиме READ COMMITED) рассматривался надысь здесь: вот оно .


случай просто с FOUND приведет к отлупу (если проектировали не левой задней, и есть ключ в накопит. табличке) в том редком случае, когда конкурент успеет вставить свою запись промеж вашей попыки апдейта, и инсерта в триггере
...
Рейтинг: 0 / 0
Триггерная функция
    #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
Триггерная функция
    #34233057
Andrey Daeron
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
4321
случай просто с FOUND приведет к отлупу (если проектировали не левой задней, и есть ключ в накопит. табличке) в том редком случае, когда конкурент успеет вставить свою запись промеж вашей попыки апдейта, и инсерта в триггере
Есть неплохая идея для таких целей лочить табличку на запись. "Во избежание".
...
Рейтинг: 0 / 0
Триггерная функция
    #34233202
Jelis
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Andrey Daeron 4321
случай просто с FOUND приведет к отлупу (если проектировали не левой задней, и есть ключ в накопит. табличке) в том редком случае, когда конкурент успеет вставить свою запись промеж вашей попыки апдейта, и инсерта в триггере
Есть неплохая идея для таких целей лочить табличку на запись. "Во избежание".
Лочить табличку хороший метод решающий большенство подобных проблемм (а то и все), но, за счет понижения производительности. Если данный код выполняеться не часто, и не так критичен для производительности, то все ок. Но, imho, способ с обработкой эксепшенса более производителен (опятьтакиже, как в той ссылке, что дал 4321).
...
Рейтинг: 0 / 0
12 сообщений из 12, страница 1 из 1
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Триггерная функция
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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