powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Как на pl/pgsql сформировать строку, а потом выполнить?
6 сообщений из 6, страница 1 из 1
Как на pl/pgsql сформировать строку, а потом выполнить?
    #39503643
an2k
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Не запрос, а например присвоение:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
DECLARE
_rec record;
_table_name varchar(32);
_field_name varchar(32);
_field_value integer;

BEGIN

_table_name = 'tab_test' ; -- вообще то это значение достается другим запросом
_field_name = 'fld_test' ; -- это значение тоже достается другим запросом

for _rec in
    select quote_ident(_field_name) from quote_ident(_table_name)
loop
    -- если бы _field_name было заранее известно, я бы сделал так:
    _field_value = _rec.fld_test; -- но это на момент написания хранимки не известно
    _field_value = _rec. || _field_name  ; -- А ЭТО НЕ РАБОТАЕТ
    EXECUTE '_field_value = _rec.' || _field_name || ';'; -- И ЭТО ТОЖЕ НЕ РАБОТАЕТ

    -- НУ ИЗ ЗА ЭТОГО И ЭТО НЕ РАБОТАЕТ - А ОЧЕНЬ НАДО (((
    select * from tab_test2 where fld_test2 = _field_value ;
end loop;



Помогите, если кто знает, плиз.
...
Рейтинг: 0 / 0
Как на pl/pgsql сформировать строку, а потом выполнить?
    #39503682
qwwq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
an2kНе запрос, а например присвоение:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
DECLARE
_rec record;
_table_name varchar(32);
_field_name varchar(32);
_field_value integer;

BEGIN

_table_name = 'tab_test' ; -- вообще то это значение достается другим запросом
_field_name = 'fld_test' ; -- это значение тоже достается другим запросом

for _rec in
    EXECUTE 'select '||quote_ident(_field_name)||' from '||quote_ident(_table_name)
loop
  xxx
end loop;



Помогите, если кто знает, плиз.
...
Рейтинг: 0 / 0
Как на pl/pgsql сформировать строку, а потом выполнить?
    #39503703
an2k
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
qwwq,

Спасибо, но только Вы поправили запрос в секции FOR, а это не столь важно.

Вопрос был именно по секции LOOP:
как сформировать конструкцию _rec._field_nam
где:
_rec - запись, которую вернул запрос в секции FOR
_field_nam - переменная, в которой хранится имя поля

Сейчас эта конструкция не работает - вместо переменной на этом месте должно быть ЗНАЧЕНИЕ,
т.е. само имя поля.

Конструкция _rec.fld_test точно будет работать,
потому что fld_test - это настоящее название поля, но как этого добиться
я не знаю, потому и прошу помощи у знающих людей.
...
Рейтинг: 0 / 0
Как на pl/pgsql сформировать строку, а потом выполнить?
    #39503745
qwwq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
an2k,

того, чего вы, как мне видится, хотите -- нужно избегать.
или пользоваться заранее типизированными рекордами.
или терять тип поля, используя скажем hstore (or json)

Код: sql
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.
42.
43.
44.
--create extension hstore;
do	
$$
declare 
	_sql text;
	r record;
	
	fld_name text:='fldname';
	fld_name1 text:='fldname1';

	result text;
BEGIN 
	EXECUTE 'SELECT 1 AS  ' || quote_ident(fld_name) ||'
		,2 AS ' || quote_ident(fld_name1)
	INTO r;

	RAISE NOTICE '%' ,r.fldname;
	RAISE NOTICE '%' ,r.fldname1;
	
	RAISE NOTICE '%' ,hstore(r); --только так, но теряем типы
	RAISE NOTICE '%	%' ,hstore(r)->fld_name1 ,fld_name1;
	
	select r.fldname1 INTO result;
	RAISE NOTICE '01 result	%' , result;
	/* -- error:
	EXECUTE 'SELECT  $1.'||quote_ident(fld_name1)||' 'USING (r)
	INTO result;
	RAISE NOTICE '02 result	%' , result;
	--*/
	-- или совсем через жжж
	EXECUTE '
		CREATE TEMP TABLE tt  ON COMMIT DROP AS
	
		SELECT 1 AS  ' || quote_ident(fld_name) ||'
		,2 AS ' || quote_ident(fld_name1)||'
		WHERE null'		
		; -- создали тип, для приведения. попортили себе карму

	EXECUTE 'SELECT  ($1::text::tt).'||quote_ident(fld_name1)||' 'USING (r)
	INTO result;
	RAISE NOTICE '02 result	%' , result;
		
END;
$$
...
Рейтинг: 0 / 0
Как на pl/pgsql сформировать строку, а потом выполнить?
    #39510138
Jackvoron
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
А что мешает написать алиас ?
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
DECLARE
_rec record;
_table_name varchar(32);
_field_name varchar(32);
_field_value integer;

BEGIN

_table_name = 'tab_test' ; -- вообще то это значение достается другим запросом
_field_name = 'fld_test' ; -- это значение тоже достается другим запросом

for _rec in
    EXECUTE 'select '||quote_ident(_field_name)||' AS my_fld from '||quote_ident(_table_name)
loop
    _field_value = _rec.my_fld;
    select * from tab_test2 where fld_test2 = _field_value ;
end loop;
...
Рейтинг: 0 / 0
Как на pl/pgsql сформировать строку, а потом выполнить?
    #39510176
qwwq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
JackvoronА что мешает написать алиас ?
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
DECLARE
_rec record;
_table_name varchar(32);
_field_name varchar(32);
_field_value integer;

BEGIN

_table_name = 'tab_test' ; -- вообще то это значение достается другим запросом
_field_name = 'fld_test' ; -- это значение тоже достается другим запросом

for _rec in
    EXECUTE 'select '||quote_ident(_field_name)||' AS my_fld from '||quote_ident(_table_name)
loop
    _field_value = _rec.my_fld;
    select * from tab_test2 where fld_test2 = _field_value ;
end loop;


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

а то, что плпгскл не полноценный язык программирования, а единственно -- херовина по конструированию скл--конструкций, доходит не сразу. там еще где--то в самом скл недоработки были, когда уместно было бы расширить применимость конструкции {row_constructor} AS rec (field type[,field type[,...]), когда заранее знаешь конструкцию своего рекорда (и пусть падает при исполнении, если не попали), а не утыкаться в незарегистрированный тип. ну и прочее. хотя с популяцией джейсонов оно вроде бы получше стало
...
Рейтинг: 0 / 0
6 сообщений из 6, страница 1 из 1
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Как на pl/pgsql сформировать строку, а потом выполнить?
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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