Подтвердить что ты не робот

Функция триггера Postgresql с параметрами

Я хочу создать триггер в таблице с именем принимает в 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);
4b9b3361

Ответ 1

Вам не нужно передавать 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 вызывается как триггер, в блоке верхнего уровня автоматически создаются несколько специальных переменных. Они: [...] NEW, [...] OLD [...]

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

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

Ответ 2

Функция триггера может иметь параметры, но вы не можете передавать эти параметры как нормальную функцию (например, аргументы в определении функции). Вы можете получить тот же результат... В python вы получаете доступ к OLD и NEW данным, как описано выше. Например, я могу использовать 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');

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

Ответ 3

Как указано Greg, триггерные функции могут принимать аргументы, но сами функции не могут объявлять параметры. Вот простой пример в 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 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 (чтобы узнать, сколько аргументов вы получили, не зацикливая их), обсуждаемые в docs. Там также информация о том, как получить имя таблицы запуска, если у вас есть основная логика, но не вполне общая для одной триггерной функции, которая охватывает несколько таблиц.