Не работает IF....ELSE, или мой мозг

KraG
Дата: 12.12.2014 13:55:38
Доброго времени суток, уважаемые форумчане.
Не нашел лучшей ветки, чем эта, ибо сабж происходит как раз в постгре.
Запилил триггерную функцию. Повесил на BEFORE INSERT. Работает все, за исключением конструкции IF. Менял функцию на "не триггерную", возвращал значения переменных. Все переменные в порядке.
Собсно код
$BODY$
DECLARE _tname varchar(25);
	_date varchar(10);
	c_q varchar;
	i_q varchar;
BEGIN
	_date = to_char(to_timestamp(NEW.eventtimestamp), 'DDMMYYYY');
	_tname = 't' || substring(NEW.userid from 25 for 36) || '_' || _date;
	c_q = 'CREATE TABLE tmp.'|| _tname ||' (
		eventid character(36) NOT NULL, 
		userid character(36) NOT NULL, 
		userfio character(50) NOT NULL, 
		turniket character(10) NOT NULL, 
		prizn character(6) NOT NULL, 
		eventtimestamp integer NOT NULL);';
	i_q = 'INSERT INTO tmp.'|| _tname ||' (eventid, userid, userfio, turniket, prizn, eventtimestamp) values (
		''' || NEW.eventid || ''',
		''' || NEW.userid || ''',
		''' || NEW.userfio || ''',
		''' || NEW.turniket || ''',
		''' || NEW.prizn || ''',
		''' || NEW.eventtimestamp || ''');';
	-- Провереряем, создана ли таблица
	PERFORM * from pg_tables where tablename like ''||_tname||'';
	IF NOT FOUND THEN
		EXECUTE c_q;
		COMMIT;
	END IF;
	EXECUTE i_q;
	RETURN NEW;
END;
$BODY$


По результатам работы функции ВСЕГДА создается таблица, даже если она уже была создана на предыдущей итерации.
Испробывал следующие варианты:
- SELECT INTO _record * from pg_tables where tablename like ''||_tname||'';
IF _record IS NULL THEN
...
END IF;

- EXECUTE 'SELECT * from pg_tables where tablename like ''||_tname||'';' INTO _varchar;
IF (char_length(_varchar) > 0) THEN
...
END IF;

Еще что то пробывал... В общем ничего не помогает. Результат один.
Готов смиренно перенести любую критику и выслушать любые варианты :-)
Maxim Boguk
Дата: 12.12.2014 14:06:03
KraG,

ваша процедура вообще не может работать
так как строка
COMMIT;
должна выдавать синтаксическую ошибку при запуске или компиляции

--Maxim Boguk
www.postgresql-consulting.ru
KraG
Дата: 12.12.2014 14:51:37
Вай, вай вай... Все обман. Никакого COMMIT там нет. Это я в огонии понавставлял всяких там непонятных слов. В исходном варианте все кошерно. Повторю...

Код
+
CREATE OR REPLACE FUNCTION temptable_create()
  RETURNS trigger AS
$BODY$
DECLARE _tname varchar(25);
	_date varchar(10);
	t_exist varchar;
	t_len integer;
	c_q varchar;
	i_q varchar;
	user_rec record;
BEGIN
	--user_rec = NULL;
	_date = to_char(to_timestamp(NEW.eventtimestamp), 'DDMMYYYY');
	_tname = 't' || substring(NEW.userid from 25 for 36) || '_' || _date;
	c_q = 'CREATE TABLE tmp.'|| _tname ||' (
		eventid character(36) NOT NULL, 
		userid character(36) NOT NULL, 
		userfio character(50) NOT NULL, 
		turniket character(10) NOT NULL, 
		prizn character(6) NOT NULL, 
		eventtimestamp integer NOT NULL);';
	i_q = 'INSERT INTO tmp.'|| _tname ||' (eventid, userid, userfio, turniket, prizn, eventtimestamp) values (
		''' || NEW.eventid || ''',
		''' || NEW.userid || ''',
		''' || NEW.userfio || ''',
		''' || NEW.turniket || ''',
		''' || NEW.prizn || ''',
		''' || NEW.eventtimestamp || ''');';
	-- Провереряем, создана ли таблица
	PERFORM * from pg_tables where tablename like ''||_tname||'';
	IF NOT FOUND THEN
		EXECUTE c_q;
	END IF;
	EXECUTE i_q;
	RETURN NEW;
END;
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;
ALTER FUNCTION temptable_create()
  OWNER TO htoito;
/\/\/\/\/\/\
Дата: 12.12.2014 14:55:24
Maxim Boguk,

Как откомпилировать -- расскажите подробнее. (Хотя бы чтобы все опечатки нашлись)

К автору:
Как Вы определили, что это именно новая таблица и она именно создается?
KraG
Дата: 12.12.2014 14:59:02
Дамы и Господа.
Волею судьбы был носом ткнут в код с конструкцией "CREATE TABLE IF NOT EXISTS...". Это прекрасно...

Но, мне все = интересно, что не так с IF...

Если кроме меня интересующихся нет, то тему можно переносить в топку. Спасибо.
SmeL_md
Дата: 12.12.2014 15:19:17
Tom Lane
EXECUTE doesn't affect FOUND, even if the statement-to-be-executed would
have. There's been some discussion about changing that, but no
movement.

regards, tom lane
get diagnostics r = ROW_COUNT;
этта
Дата: 12.12.2014 15:26:29
SmeL_md,
он after PERFORM


2 ТС выведите перед фаундом в нотисы все переменные. Ну и в нем еще схеманейм укажите,
Павел Лузанов
Дата: 12.12.2014 15:26:59
KraG
Но, мне все = интересно, что не так с IF...

Может посмотреть что не так с like ?
ну, этта
Дата: 12.12.2014 15:28:18
этта,

ну и quote_ident() не вредно пользовать, если в наборе буковок не уверены
KraG
Дата: 12.12.2014 15:47:21
/\/\/\/\/\/\
Maxim Boguk,

Как откомпилировать -- расскажите подробнее. (Хотя бы чтобы все опечатки нашлись)

К автору:
Как Вы определили, что это именно новая таблица и она именно создается?


Двумя путями:
- узрел по-средствам pgadmin
- встретил в результате выполнения select * from pg_tables where tablename like 't%' новую строку, которой ранее выполнения функции там не было

Ну и эмпирическими всякими там путями...