Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Создание одной функции на все триггеры / 7 сообщений из 7, страница 1 из 1
08.07.2014, 21:52:53
    #38691157
TaIRou
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Создание одной функции на все триггеры
Доброго времени суток.
Бьюсь над созданием функции для триггеров, которая бы могла реагировать на события вставки новой записи в таблицу и сохранять идентификатор новой записи в другую спец. таблицу в случае, если этот идентификатор больше, чем уже хранящийся в этой спец. таблице.

Но не нашел возможности сказать функции, какое поле яв-ся идентификатором. Лишь нашел возможность указать таблицу...

Спасибо за любую помощь.

Структура спец. таблицы ALL_MAX_ID следующая: два поля NAMETABLE - хранящая перечень наименований всех обслуживаемых таблиц и поле MAX_ID - со значением самого большого идентификатора, который был.

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
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();
...
Рейтинг: 0 / 0
09.07.2014, 01:42:53
    #38691285
LeXa NalBat
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Создание одной функции на все триггеры
CREATE TRIGGER
arguments
An optional comma-separated list of arguments to be provided to the function when the trigger is executed. The arguments are literal string constants. Simple names and numeric constants can be written here, too, but they will all be converted to strings. Please check the description of the implementation language of the trigger function to find out how these arguments can be accessed within the function; it might be different from normal function arguments.

40.9. Trigger Procedures
TG_ARGV[]
Data type array of text; the arguments from the CREATE TRIGGER statement. The index counts from 0. Invalid indexes (less than 0 or greater than or equal to tg_nargs) result in a null value.
...
Рейтинг: 0 / 0
09.07.2014, 02:50:41
    #38691301
TaIRou
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Создание одной функции на все триггеры
Я пробовал делать так
Код: plsql
1.
2.
CREATE TRIGGER SAVE_MAX_ID AFTER INSERT ON mytable
    FOR EACH ROW EXECUTE PROCEDURE SAVE_MAX_ID('fieldName');



А потом внутри функции вытаскивать TG_ARGV[0]

Вот так
Код: plsql
1.
2.
3.
4.
5.
6.
7.
CREATE FUNCTION SAVE_MAX_ID() RETURNS trigger AS $$
BEGIN
	  	UPDATE ALL_MAX_ID SET MAX_ID=NEW.TG_ARGV[0]
		WHERE NAMETABLE=TG_TABLE_NAME AND MAX_ID < NEW.TG_ARGV[0];
RETURN NEW;
END;
$$ LANGUAGE plpgsql; 



Но это не работает, ды не должно работать, ведь я не могу вот так вот просто менять фактически текст функции
Или я запутался...
...
Рейтинг: 0 / 0
09.07.2014, 11:14:39
    #38691608
LeXa NalBat
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Создание одной функции на все триггеры
используйте EXECUTE UPDATE ...

40.5.4. Executing Dynamic Commands
...
Рейтинг: 0 / 0
09.07.2014, 18:45:33
    #38692297
Gold_
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Создание одной функции на все триггеры
...
Рейтинг: 0 / 0
09.07.2014, 22:06:36
    #38692419
TaIRou
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Создание одной функции на все триггеры
Ребят, спасибо огромное за помощь, очень помог пример, да и аргументы тоже решил применить.
Оказывается процедуры умеют весьма много.

Не отважусь пока лезть в информационную схему.
Указываю ключевое поле напрямик, что наверно не универсально и даже в чем-то ошибочно.

Вот проверил работоспособность на двух таблицах.
Вроде теперь душа спокойна: функция одна - триггеров много.
Конечно, может и глупо теперь спрашивать, но может есть более изящная возможность сохранять максимальные идентификаторы в таблицах, которые там когда-то были.

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
CREATE OR REPLACE FUNCTION SAVE_MAX_ID()
RETURNS trigger
LANGUAGE plpgsql 
AS $$
BEGIN
EXECUTE 'UPDATE TABLE_ID SET MAX_ID = ($1).' || TG_ARGV[0] || ' WHERE NAMETABLE= ' || quote_literal(TG_TABLE_NAME) || ' AND MAX_ID < ($1).' || TG_ARGV[0] USING NEW;
RETURN NEW;
END;
$$; 

CREATE TRIGGER MAX_ID_1 AFTER INSERT ON table1
    FOR EACH ROW EXECUTE PROCEDURE SAVE_MAX_ID('id');
	
CREATE TRIGGER MAX_ID_2 AFTER INSERT ON table2
    FOR EACH ROW EXECUTE PROCEDURE SAVE_MAX_ID('id');



Спасибо еще раз!
...
Рейтинг: 0 / 0
10.07.2014, 10:24:45
    #38692759
LeXa NalBat
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Создание одной функции на все триггеры
TaIRouКонечно, может и глупо теперь спрашивать, но может есть более изящная возможность сохранять максимальные идентификаторы в таблицах, которые там когда-то были.неточный способ, не хранить, а вычислять. если идентификатор при вставке строк всегда увеличивается автоматически по сиквенсу, то вызвать nextval(). но это значение будет (немного?) больше максимального в таблице. и сиквенс нельзя будет менять через setval(), например сдвинуть вниз.

TaIRouEXECUTE 'UPDATE TABLE_ID SET MAX_ID = ($1).' || TG_ARGV[0] || ' WHERE NAMETABLE= ' || quote_literal(TG_TABLE_NAME) || ' AND MAX_ID < ($1).' || TG_ARGV[0] USING NEW;наверное название поля надо тоже обернуть quote_literal(TG_ARGV[0])

и для чего USING NEW, разве нельзя NEW указать прямо внутри строки запроса?
EXECUTE 'UPDATE TABLE_ID SET MAX_ID = NEW.' || TG_ARGV[0] || ...
...
Рейтинг: 0 / 0
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Создание одной функции на все триггеры / 7 сообщений из 7, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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