Доброго времени суток.
Бьюсь над созданием функции для триггеров, которая бы могла реагировать на события вставки новой записи в таблицу и сохранять идентификатор новой записи в другую спец. таблицу в случае, если этот идентификатор больше, чем уже хранящийся в этой спец. таблице.
Но не нашел возможности сказать функции, какое поле яв-ся идентификатором. Лишь нашел возможность указать таблицу...
Спасибо за любую помощь.
Структура спец. таблицы ALL_MAX_ID следующая: два поля NAMETABLE - хранящая перечень наименований всех обслуживаемых таблиц и поле MAX_ID - со значеним самого большого идентификатора, который был.
CREATE FUNCTION SAVE_MAX_ID() RETURNS TRIGGER AS $$ BEGIN UPDATE ALL_MAX_ID SET MAX_ID=NEW.id WHERE NAMETABLE=TG_TABLE_NAME AND MAX_ID < NEW.id; RETURN NEW; END; $$ LANGUAGE plpgsql; CREATE TRIGGER SAVE_MAX_ID AFTER INSERT ON mytable FOR EACH ROW EXECUTE PROCEDURE SAVE_MAX_ID();
> Но не нашел возможности
> Но не нашел возможности сказать функции, какое поле яв-ся идентификатором.
Вы не про это случайно?
http://postgresql.ru.net/docs/extented_FAQ.html#Q003
Для полей таблицы это также справедливо
Я не знаю, о каких функция
Я не знаю, о каких функция идет речь в примере.
Я говорю о тех, которые пишутся на процедурном языке и вызываются как триггеры.
То есть об этом
http://postgresql.ru.net/manual/plpgsql-trigger.html
Они имеют набор встроенных переменных.
Из них в TG_TABLE_NAME хранится имя таблицы, на которой сработал триггер, вызвавший функцию.
А в переменной NEW хранится запись, вот как из этой записи выцепить значение столбца, не указывая напрямую его наименование в функции.
Есть вообще возможности в запросе обращаться к полям таблицы, не используя их наименования, а например позицию в таблице?
Ещё раз внимательно
Ещё раз внимательно перечитайте то, что было написано по ссылке которую я привёл и постарайтесь осмыслить.
Потому что ваши вопросы свидетельствуют о том. что вы ничего не поняли из написанного.
Вот такая конструкция делает
Вот такая конструкция делает то, что мне нужно и пока меня устраивает.
Помогла вот эта статья
http://wiki.postgresql.org/wiki/PL/pgSQL_Dynamic_Triggers
А вот в том документе про хранимые процедуры указывался процесс компиляции, но у меня его нет или я снова, чего-то не так прочитал?
Спасибо за терпение)
Ещё раз попытаюсь
Ещё раз попытаюсь объяснить.
Когда вы создаёте функцию она компилируется и сохраняется для дальнейшего использования. Это не зависит от вашего желания. Это просто происходит.
На момент компиляции функция ДОЛЖНА знать с какой КОНКРЕТНО таблицей она будет работать и с какими КОНКРЕТНО полями. В противном случае на этапе компиляции невозможно проверить корректность работы функции, ибо в процессе работы функция ДОЛЖНА быть уверена, что именно эти поля ТОЧНО найдутся в той таблице и что они будут того самого типа. Теперь понятно?
EXECUTE является выходом из положения - этот вызов не компилируется и позволяет задать аргументы. EXECUTE - это практически вызов динамически обрабатываемого запроса, т.е. запроса который анализируется уже на ходу: синтаксический парсинг, проверка таблиц, типов и т.д. Это замедляет работу системы, а триггеры в некоторых случаях должны работать очень быстро и отрабатывать сотни и тысячи раз в секунду.
Осталось прояснить тогда вот
Осталось прояснить тогда вот такой момент.
TG_TABLE_NAME - это переменная, а значит имеется невыполнение условия "функция ДОЛЖНА знать с какой КОНКРЕТНО таблицей она будет работать". А вот такая функция все-таки работала.
Раз EXECUTE - зло во благо, то это костыль. Может можно обойтись без EXECUTE? (Если наименование ключевого поля не id, как бы его вот простенько обозначить)
Но я не требую, пуская и так поработает пока.
> А вот такая функция
> А вот такая функция все-таки работала.
Судя по запросу TG_TABLE_NAME это не имя таблиц и даже не имя поля, а ЗНАЧЕНИЕ для конкретного поля в конкретной таблице, т.е. условия наличия конкретной таблицы и конкретного поля в функции соблюдены. А значения могут меняться, потому что иначе функции не нужны были бы