Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Не работает IF....ELSE, или мой мозг / 23 сообщений из 23, страница 1 из 1
12.12.2014, 13:55:38
    #38832423
KraG
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Не работает IF....ELSE, или мой мозг
Доброго времени суток, уважаемые форумчане.
Не нашел лучшей ветки, чем эта, ибо сабж происходит как раз в постгре.
Запилил триггерную функцию. Повесил на 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
12.12.2014, 14:06:03
    #38832443
Maxim Boguk
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Не работает IF....ELSE, или мой мозг
KraG,

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

--Maxim Boguk
www.postgresql-consulting.ru
...
Рейтинг: 0 / 0
12.12.2014, 14:51:37
    #38832520
KraG
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Не работает IF....ELSE, или мой мозг
Вай, вай вай... Все обман. Никакого 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
12.12.2014, 14:55:24
    #38832528
/\/\/\/\/\/\
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Не работает IF....ELSE, или мой мозг
Maxim Boguk,

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

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

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

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


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

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

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

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

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

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


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

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

дата уже в _tname
...
Рейтинг: 0 / 0
12.12.2014, 16:27:04
    #38832716
Павел Лузанов
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Не работает IF....ELSE, или мой мозг
TC, извиняй это я сам торможу, с датой в конце всё в порядке. Причина другая.
...
Рейтинг: 0 / 0
12.12.2014, 16:53:54
    #38832759
KraG
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Не работает IF....ELSE, или мой мозг
этта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
12.12.2014, 16:58:03
    #38832770
KraG
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Не работает IF....ELSE, или мой мозг
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
12.12.2014, 16:59:47
    #38832776
этта
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Не работает IF....ELSE, или мой мозг
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
12.12.2014, 17:04:47
    #38832787
KraG
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Не работает IF....ELSE, или мой мозг
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
12.12.2014, 17:05:49
    #38832788
этта
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Не работает IF....ELSE, или мой мозг
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
12.12.2014, 17:07:32
    #38832793
KraG
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Не работает IF....ELSE, или мой мозг
этта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
12.12.2014, 17:08:51
    #38832794
KraG
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Не работает IF....ELSE, или мой мозг
этта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
12.12.2014, 17:12:19
    #38832797
этта
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Не работает IF....ELSE, или мой мозг
KraG• почему like
В случае со стрингами like мне кажется иделогически [более] верным. Это "врожденно", в смысле с момента моих первых полетов на SQL.
врождённый ползать летает камнем

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


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