powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Не работает IF....ELSE, или мой мозг
23 сообщений из 23, страница 1 из 1
Не работает IF....ELSE, или мой мозг
    #38832423
KraG
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Доброго времени суток, уважаемые форумчане.
Не нашел лучшей ветки, чем эта, ибо сабж происходит как раз в постгре.
Запилил триггерную функцию. Повесил на BEFORE INSERT. Работает все, за исключением конструкции IF. Менял функцию на "не триггерную", возвращал значения переменных. Все переменные в порядке.
Собсно код
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
$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;

Еще что то пробывал... В общем ничего не помогает. Результат один.
Готов смиренно перенести любую критику и выслушать любые варианты :-)
...
Рейтинг: 0 / 0
Не работает IF....ELSE, или мой мозг
    #38832443
Фотография Maxim Boguk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
KraG,

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

--Maxim Boguk
www.postgresql-consulting.ru
...
Рейтинг: 0 / 0
Не работает IF....ELSE, или мой мозг
    #38832520
KraG
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Вай, вай вай... Все обман. Никакого COMMIT там нет. Это я в огонии понавставлял всяких там непонятных слов. В исходном варианте все кошерно. Повторю...

Код
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
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;

...
Рейтинг: 0 / 0
Не работает IF....ELSE, или мой мозг
    #38832528
/\/\/\/\/\/\
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Maxim Boguk,

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

К автору:
Как Вы определили, что это именно новая таблица и она именно создается?
...
Рейтинг: 0 / 0
Не работает IF....ELSE, или мой мозг
    #38832531
KraG
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Дамы и Господа.
Волею судьбы был носом ткнут в код с конструкцией "CREATE TABLE IF NOT EXISTS...". Это прекрасно...

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

Если кроме меня интересующихся нет, то тему можно переносить в топку. Спасибо.
...
Рейтинг: 0 / 0
Не работает IF....ELSE, или мой мозг
    #38832554
Фотография SmeL_md
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Tom LaneEXECUTE 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;
...
Рейтинг: 0 / 0
Не работает IF....ELSE, или мой мозг
    #38832569
этта
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
SmeL_md,
он after PERFORM


2 ТС выведите перед фаундом в нотисы все переменные. Ну и в нем еще схеманейм укажите,
...
Рейтинг: 0 / 0
Не работает IF....ELSE, или мой мозг
    #38832570
Павел Лузанов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
KraGНо, мне все = интересно, что не так с IF...
Может посмотреть что не так с like ?
...
Рейтинг: 0 / 0
Не работает IF....ELSE, или мой мозг
    #38832572
ну, этта
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
этта,

ну и quote_ident() не вредно пользовать, если в наборе буковок не уверены
...
Рейтинг: 0 / 0
Не работает IF....ELSE, или мой мозг
    #38832612
KraG
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
/\/\/\/\/\/\Maxim Boguk,

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

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

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

Ну и эмпирическими всякими там путями...
...
Рейтинг: 0 / 0
Не работает IF....ELSE, или мой мозг
    #38832656
KraG
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Господа, не все сразу)
Попробую по порядку:
- to SmeL_md, попрбую после того, как нажму "Опубликовать";
- to этта, прошу прощения за нубизм, но в сети я нашел только вариант с
Код: plsql
1.
RAISE NOTICE 'i want to print % and %', var1,var2;


Так сделать? А за quote_ident() спасибо. Милая функция.
- to Павел Лузанов, за нотками сарказма мне слышется намек... Но вот только не пойму, что не так с like? Возможно quote_ident() поможет что то объяснить
...
Рейтинг: 0 / 0
Не работает IF....ELSE, или мой мозг
    #38832699
Павел Лузанов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
KraG- to Павел Лузанов, за нотками сарказма мне слышется намек... Но вот только не пойму, что не так с like?
В триггере к имени таблицы в конце дописывается дата, поэтому like я бы записал так:
Код: plsql
1.
where tablename like _tname||'%';
...
Рейтинг: 0 / 0
Не работает IF....ELSE, или мой мозг
    #38832700
Фотография SmeL_md
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: sql
1.
PERFORM * from pg_tables where tablename like ''||_tname||'';

• почему like
• почему не учитываем schemaname
...
Рейтинг: 0 / 0
Не работает IF....ELSE, или мой мозг
    #38832705
Фотография SmeL_md
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Павел ЛузановВ триггере к имени таблицы в конце дописывается дата, поэтому like я бы записал так:
Код: plsql
1.
where tablename like _tname||'%';

дата уже в _tname
...
Рейтинг: 0 / 0
Не работает IF....ELSE, или мой мозг
    #38832716
Павел Лузанов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
TC, извиняй это я сам торможу, с датой в конце всё в порядке. Причина другая.
...
Рейтинг: 0 / 0
Не работает IF....ELSE, или мой мозг
    #38832759
KraG
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
эттаSmeL_md,
он after PERFORM


2 ТС выведите перед фаундом в нотисы все переменные. Ну и в нем еще схеманейм укажите,

1. Про переменные
Код: plsql
1.
2.
3.
4.
_record := NULL;
SELECT INTO _record * from pg_tables where tablename like ''||_tname||'';
PERFORM * from pg_tables where tablename like ''||_tname||'';
RAISE NOTICE 'i want to print _tname - % , _date -  % , _record -  %', _tname,_date,_record;



"дает"

Код: html
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
NOTICE:  i want to print _tname - t00000000009E_12122014 , _date -  12122014 , _record -  (,,,,,,)
<h1>Software error:</h1>
<pre>DBD::Pg::st execute failed: ERROR:  relation &quot;t00000000009e_12122014&quot; already exists
CONTEXT:  SQL statement &quot;CREATE TABLE tmp.t00000000009E_12122014 (
		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);&quot;
PL/pgSQL function temptable_create() line 32 at EXECUTE statement at ./exchange.pl line 67.
</pre>



Т.е. переменные себя чувствуют хорошо. За исключением _record, который "пуст". Т.е.
Код: plsql
1.
SELECT INTO _record * from pg_tables where tablename like ''||_tname||'';


отрабатывает не так, как надо :)
Однако, _record != NULL.
Значит конструкция
Код: plsql
1.
2.
IF _record IS NOT NULL THEN
select '_record is not null';


должна отработать


2. Про quote_ident()
Код: plsql
1.
EXECUTE 'SELECT * from pg_tables where tablename like '|| quote_ident(_tname)||'' INTO _record;


принесла следующие плоды
Код: html
1.
2.
DBD::Pg::st execute failed: ERROR:  column &quot;t00000000009E_12122014&quot; does not exist
LINE 1: SELECT * from pg_tables where tablename like &quot;t00000000009E_...
...
Рейтинг: 0 / 0
Не работает IF....ELSE, или мой мозг
    #38832770
KraG
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
SmeL_mdTom LaneEXECUTE 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;

Следующий код
Код: plsql
1.
2.
3.
4.
5.
00 EXECUTE ('SELECT * from pg_catalog.pg_tables where tablename like '''|| _tname||'''') INTO _record;
10 get diagnostics r_1 = ROW_COUNT;
20 PERFORM * from pg_tables where tablename like ''||_tname||'';
30 get diagnostics r_2 = ROW_COUNT;
40 RAISE NOTICE 'i want to print _tname - % , _date -  % , _record -  % , r_1 - % , r_2 - %', _tname,_date,_record,r_1,r_2;



дает следующий результат

Код: html
1.
NOTICE:  i want to print _tname - t00000000009E_12122014 , _date -  12122014 , _record -  (,,,,,,) , r_1 - 0 , r_2 - 0



Добры молодцы, поясните, пожалуйста, почему r_1 - 0 , r_2 - 0 ???
...
Рейтинг: 0 / 0
Не работает IF....ELSE, или мой мозг
    #38832776
этта
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
KraG<>
2. Про quote_ident()
Код: plsql
1.
EXECUTE 'SELECT * from pg_tables where tablename like '|| quote_ident(_tname)||'' INTO _record;


принесла следующие плоды
Код: html
1.
2.
DBD::Pg::st execute failed: ERROR:  column "t00000000009E_12122014" does not exist
LINE 1: SELECT * from pg_tables where tablename like "t00000000009E_...


в случае литераоа нужен quote_nullable, а в случае идентификатора (в том же ддл) -- quote_ident

а с вами всё ясно -- сделайте
Код: sql
1.
_tname :=lower(_tname)

-- с вас хватит.
...
Рейтинг: 0 / 0
Не работает IF....ELSE, или мой мозг
    #38832787
KraG
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
SmeL_md
Код: sql
1.
PERFORM * from pg_tables where tablename like ''||_tname||'';


• почему like
• почему не учитываем schemaname

• почему like
В случае со стрингами like мне кажется иделогически [более] верным. Это "врожденно", в смысле с момента моих первых полетов на SQL. Возможно, я категорически заблуждаюсь, но пока не вижу в чем.

• почему не учитываем schemaname
pg_tables вроде один. По крайней мере в результате выполнения
Код: plsql
1.
SELECT * from pg_tables


я вижу все таблицы всех схем. Потому не стал заморачиваться со schemaname.
...
Рейтинг: 0 / 0
Не работает IF....ELSE, или мой мозг
    #38832788
этта
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
KraGэттаSmeL_md,
он after PERFORM


2 ТС выведите перед фаундом в нотисы все переменные. Ну и в нем еще схеманейм укажите,

1. Про переменные
Код: plsql
1.
2.
3.
4.
_record := NULL;
SELECT INTO _record * from pg_tables where tablename like ''||_tname||'';
PERFORM * from pg_tables where tablename like ''||_tname||'';
RAISE NOTICE 'i want to print _tname - % , _date -  % , _record -  %', _tname,_date,_record;



"дает"

Код: html
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
NOTICE:  i want to print _tname - t00000000009E_12122014 , _date -  12122014 , _record -  (,,,,,,)
<h1>Software error:</h1>
<pre>DBD::Pg::st execute failed: ERROR:  relation "t00000000009e_12122014" already exists
CONTEXT:  SQL statement "CREATE TABLE tmp.t00000000009E_12122014 (
		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);"
PL/pgSQL function temptable_create() line 32 at EXECUTE statement at ./exchange.pl line 67.
</pre>



Т.е. переменные себя чувствуют хорошо. За исключением _record, который "пуст". Т.е.
Код: plsql
1.
SELECT INTO _record * from pg_tables where tablename like ''||_tname||'';


отрабатывает не так, как надо :)
Однако, _record != NULL.
Значит конструкция
Код: plsql
1.
2.
IF _record IS NOT NULL THEN
select '_record is not null';


должна отработать


2. Про quote_ident()
Код: plsql
1.
EXECUTE 'SELECT * from pg_tables where tablename like '|| quote_ident(_tname)||'' INTO _record;


принесла следующие плоды
Код: html
1.
2.
DBD::Pg::st execute failed: ERROR:  column "t00000000009E_12122014" does not exist
LINE 1: SELECT * from pg_tables where tablename like "t00000000009E_...



как у мсье со зрением ?
...
Рейтинг: 0 / 0
Не работает IF....ELSE, или мой мозг
    #38832793
KraG
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
эттаKraG<>
2. Про quote_ident()
Код: plsql
1.
EXECUTE 'SELECT * from pg_tables where tablename like '|| quote_ident(_tname)||'' INTO _record;


принесла следующие плоды
Код: html
1.
2.
DBD::Pg::st execute failed: ERROR:  column "t00000000009E_12122014" does not exist
LINE 1: SELECT * from pg_tables where tablename like "t00000000009E_...


в случае литераоа нужен quote_nullable, а в случае идентификатора (в том же ддл) -- quote_ident

а с вами всё ясно -- сделайте
Код: sql
1.
_tname :=lower(_tname)

-- с вас хватит.

Глазастый :) Спасибо
...
Рейтинг: 0 / 0
Не работает IF....ELSE, или мой мозг
    #38832794
KraG
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
эттаKraGпропущено...


1. Про переменные
Код: plsql
1.
2.
3.
4.
_record := NULL;
SELECT INTO _record * from pg_tables where tablename like ''||_tname||'';
PERFORM * from pg_tables where tablename like ''||_tname||'';
RAISE NOTICE 'i want to print _tname - % , _date -  % , _record -  %', _tname,_date,_record;



"дает"

Код: html
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
NOTICE:  i want to print _tname - t00000000009E_12122014 , _date -  12122014 , _record -  (,,,,,,)
<h1>Software error:</h1>
<pre>DBD::Pg::st execute failed: ERROR:  relation "t00000000009e_12122014" already exists
CONTEXT:  SQL statement "CREATE TABLE tmp.t00000000009E_12122014 (
		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);"
PL/pgSQL function temptable_create() line 32 at EXECUTE statement at ./exchange.pl line 67.
</pre>



Т.е. переменные себя чувствуют хорошо. За исключением _record, который "пуст". Т.е.
Код: plsql
1.
SELECT INTO _record * from pg_tables where tablename like ''||_tname||'';


отрабатывает не так, как надо :)
Однако, _record != NULL.
Значит конструкция
Код: plsql
1.
2.
IF _record IS NOT NULL THEN
select '_record is not null';


должна отработать


2. Про quote_ident()
Код: plsql
1.
EXECUTE 'SELECT * from pg_tables where tablename like '|| quote_ident(_tname)||'' INTO _record;


принесла следующие плоды
Код: html
1.
2.
DBD::Pg::st execute failed: ERROR:  column "t00000000009E_12122014" does not exist
LINE 1: SELECT * from pg_tables where tablename like "t00000000009E_...



как у мсье со зрением ?

Да видел уже, видел предыдущее сообщение, грубиян :) Лоханулся. Признаю косяк. Спасибо за время.
...
Рейтинг: 0 / 0
Не работает IF....ELSE, или мой мозг
    #38832797
этта
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
KraG• почему like
В случае со стрингами like мне кажется иделогически [более] верным. Это "врожденно", в смысле с момента моих первых полетов на SQL.
врождённый ползать летает камнем

-- за грубияна ответишь, нашЪ летунЪ
...
Рейтинг: 0 / 0
23 сообщений из 23, страница 1 из 1
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Не работает IF....ELSE, или мой мозг
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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