Функция запуска Postgresql с параметрами - PullRequest
25 голосов
/ 11 октября 2011

Я хочу создать триггер для таблицы с именем , которая занимает в postgresql для обновления значения в другой таблице с именем student .Но я получаю сообщение об ошибке, что есть синтаксическая ошибка рядом с "OLD".Я не понимаю, что с этим не так.Это мой код:

CREATE OR REPLACE FUNCTION upd8_cred_func
      (id1 VARCHAR, gr1 VARCHAR,id2 VARCHAR, gr2 VARCHAR) 
      RETURNS void AS $$
 BEGIN
    IF  (id1=id2 and gr1 is null and gr2 is not null) THEN 
        update student set tot_cred = tot_cred + 6 where id = id1;
    END IF;
    RETURN;
 END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER upd8_cred
    AFTER UPDATE ON takes
    FOR EACH ROW
    EXECUTE PROCEDURE upd8_cred_func(OLD.id,OLD.grade,NEW.id,NEW.grade);

Ответы [ 3 ]

28 голосов
/ 11 октября 2011

Вам не нужно передавать NEW и OLD в качестве параметров функции триггера. Они автоматически доступны там:

http://www.postgresql.org/docs/9.1/interactive/trigger-definition.html:

Функция триггера должна быть объявлена ​​как функция, не имеющая аргументов и возвращающая тип триггера. (Функция триггера получает свой ввод через специально переданную структуру TriggerData, а не в виде аргументов обычной функции.)

О записях, переданных процедуре запуска, см. http://www.postgresql.org/docs/9.1/interactive/plpgsql-trigger.html:

Когда в качестве триггера вызывается функция PL / pgSQL, в блоке верхнего уровня автоматически создается несколько специальных переменных. Это: [...] НОВЫЙ, [...] СТАРЫЙ [...]

Как указано в комментарии ниже SeldomNeedy , вы все равно можете передавать и использовать параметры для функции триггера. Вы объявляете функцию как не имеющую параметров, но когда определяет триггер (по CREATE TRIGGER), вы можете добавить некоторые из них.

Они будут доступны для триггера как TG_NARG (количество таких параметров) и TG_ARGV[] (массив текст значений).

15 голосов
/ 12 ноября 2015

Как указано Грег , триггерные функции могут принимать аргументы, но сами функции не могут иметь объявленные параметры. Вот простой пример в plpgsql:

CREATE TABLE my_table ( ID SERIAL PRIMARY KEY ); -- onelined for compactness

CREATE OR REPLACE FUNCTION raise_a_notice() RETURNS TRIGGER AS
$$
DECLARE
    arg TEXT;
BEGIN
    FOREACH arg IN ARRAY TG_ARGV LOOP
        RAISE NOTICE 'Why would you pass in ''%''?',arg;
    END LOOP;
    RETURN NEW; -- in plpgsql you must return OLD, NEW, or another record of table's type
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER no_inserts_without_notices BEFORE INSERT ON my_table
FOR EACH ROW EXECUTE PROCEDURE raise_a_notice('spoiled fish','stunned parrots');

INSERT INTO my_table DEFAULT VALUES;

-- the above kicks out the following:
--
-- NOTICE:  Why would you pass in 'spoiled fish'?
-- NOTICE:  Why would you pass in 'stunned parrots'?
--

Есть несколько других полезностей, таких как TG_NARGS (чтобы узнать, сколько аргументов вы получили, не просматривая их), которые обсуждались в документах . Там также есть информация о том, как получить имя триггерной таблицы в случае, если у вас есть, в основном, не совсем общая логика для одной триггерной функции, которая охватывает несколько таблиц.

13 голосов
/ 16 января 2014

Функция триггера может иметь параметры, но эти параметры нельзя передавать как обычную функцию (например, аргументы в определении функции).Вы можете получить тот же результат ... В Python вы получаете доступ к СТАРЫМ и НОВЫМ данным, как описано в ответе выше.Например, я могу использовать TD ['new'] ['column_name'] в python для ссылки на новые данные для column_name.У вас также есть доступ к специальной переменной TD ['args'].Итак, если вам нравится:

create function te() returns trigger language plpython2u as $function$
    plpy.log("argument passed 1:%s 2:%s" %(TD['args'][0], TD['args'][1], ))
$function$

create constraint trigger ta after update of ttable
for each for execute procedure te('myarg1','myarg2');

Разумеется, эти аргументы являются статическими, но они полезны при вызове общей функции триггера из нескольких объявлений триггера.Я почти уверен, что такие же переменные доступны для других языков хранимых процедур.(извините, если код не работает дословно, но я практикую эту технику, поэтому я знаю, что вы можете передавать аргументы!).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...