powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Как получить все поля Record'а
10 сообщений из 10, страница 1 из 1
Как получить все поля Record'а
    #32600638
centur
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вопрос вот в чем - в процедуре динамически форммируется запрос, т.е. каждый раз выборка полей может отличаться, Далее необходимо по всем записям в цикле пройти и осуществить действия. Т.к. выборка каждый раз разная (кол-во полей) - жестко зашить не выходит. Вот вопрос - как получить список этих полей и их значений. Вернее получить список полей могу (запрос формирую сам), но как теперь получить значения этих полей которые в recordе . типа переменная fld_name=''kod_ved''
как получить значение rec.kod_ved. Или для триггера на таблице - зная названия полей, получить значения NEW.pole1 и OLD.pole1 НЕ зашивая жестко в триггерной функции pole1 и pole2.
...
Рейтинг: 0 / 0
Период между сообщениями больше года.
Как получить все поля Record'а
    #33499735
4321
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
UP тему

в таком разрезе:
ХОЧУ перебрать все поля переменной типа рекорд по порядку (по числовому индексу). Как? (т.е. можно ли такое).

контекст: идет сравнение старой записи с NEW.* полей порядка 40. надо сравнить первые 37 (3 служебных) - и вынести вердикт об изменении. (что-то типа выгрузки удаленных данных с контролем реплик).

есТли есть идеи другого плана (помимо обращения к полю записи по числовому индексу) - тоже просьба поделицца. (я чел негордый - могу и все поля перебрать поименно - но просто уж вопрос слишком часто возникает)
...
Рейтинг: 0 / 0
Как получить все поля Record'а
    #33501145
фффф
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
IMHO на pl/pgsql никак. А так как на других динамических языках это делается запросто, то упросить добавить такой функционал в pl/pgsql сложно.

Остается либо писать на перле|пайтоне, либо использовать какое-нибудь средство моделирования (например PowerDesigner) с макроязыком для генерации pl/pgsql триггеров, либо написать генератор кода самому.

Можно гибридный вариант сделать: два триггера, один на перле делает только сравнение и ставит в вспомогательном поле или глобальной переменной true|false, а второй на pgsql разруливает всю бизнес-логику.
...
Рейтинг: 0 / 0
Как получить все поля Record'а
    #33501595
4321
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ффффОстается либо писать на перле|пайтоне, либо использовать какое-нибудь средство моделирования (например PowerDesigner) с макроязыком для генерации pl/pgsql триггеров, либо написать генератор кода самому.
ну есь и полуручные способы. (немножко аксесса + ворд с массовой заменой, табличными преобразованиями и т.п.)

С другой стороны в постгресс есть операторы сравения строк (RECORD) целиком, но кажется нет оператора сравнивания подстроки (как указать сравниваемую часть подстроки?). опять же проблема - нет (я не знаю, скажем так, ибо вероятно что таки есть) _удобного_ оператора, делающего проверку "неизменности" (а не равенства) как для строк, так и для _всех_ типов:
[|NOT] ((a=b) OR ((a IS NULL) AND (b IS NULL))
(что странно, ибо кажется что унутренне его проверить даже проще чем "="), а писать по ф-ии на каждый сравниваемый тип - слишком жирно.
ткните носом, если я неправ попо воду оператора.
...
Рейтинг: 0 / 0
Как получить все поля Record'а
    #33504356
Funny_Falcon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: plaintext
1.
SELECT NULL IS DISTINCT FROM 'не нулл';
...
Рейтинг: 0 / 0
Как получить все поля Record'а
    #33504770
4321
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Funny_Falcon
Код: plaintext
1.
SELECT NULL IS DISTINCT FROM 'не нулл';
сенькаю. крутил я этот вариант, только с рядами (ROW)
Код: plaintext
1.
2.
3.
4.
5.
6.
SELECT
CASE WHEN ROW('Null','Null') IS DISTINCT FROM ROW('Null','Null')
THEN
	'изменен'
ELSE
	'неизменен'
END;
, но почему-то не принял на свой счет (поспешил видимо) -что-то на перший взгля не подошло. Наверное так и перепишу.
(а то ж с NOT вообше трехетажно получилось-
...IF NOT COALESCE((a=a1) OR ...),FALSE)
...
ELSIF NOT COALESCE((b=b1) OR ...),FALSE)

____
ЗЫ
-кстати, кажется придумал, как сравнивать части рядов _после вставки_, не переписывая всех атрибутофф - создать усеченный (на служебные поля) вью, и брать ряды запросами к нему. Но мне это нужно в триггере _до_. т.ч. там как обрезать new.* не перечисляя полей неясно (к тому же в 7.3. нельзя new положить в другой Record - запрос видите ли не рульный).
...
Рейтинг: 0 / 0
Как получить все поля Record'а
    #33508276
4321
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
вот кажется нашел, почему не надо пользовать IS DISTINCT FROM

Код: plaintext
1.
2.
3.
4.
5.
6.
...
RAISE NOTICE \'_lastold.okei %\', _lastold.okei;
RAISE NOTICE \'NEW.okei %\',  NEW.okei;
_isupdated := (select _lastold.okei  IS DISTINCT FROM  NEW.okei);
--_isupdated := tRUE;
RAISE NOTICE \'_isupdated %\',_isupdated;
...
читаю:
Код: plaintext
1.
2.
NOTICE:  _lastold.okei  123 
NOTICE:  NEW.okei <NULL>
NOTICE:  _isupdated f
проверяю
Код: plaintext
1.
SELECT   123  IS DISTINCT FROM null
t
сыршенно непонятный результатт. то ли я к вечеру тяпницы "никакой", то ли еще чего. (селект и скобицы я там, в присвоении, приписал позже, без них та же муть )
Т.ч. верну ка я гробики из коалкскав и прочей бодяги - оно канешно гробовидно, зато работаить.


ЗЫ. проверил на догадку о баге именно для plpg, нет - для констант то сравнивает:
Код: plaintext
1.
--_isupdated :=  (_lastold.okei) IS DISTINCT FROM (NEW.okei);
_isupdated :=  1  IS DISTINCT FROM NULL;
постгрес 7.3.4
...
Рейтинг: 0 / 0
Как получить все поля Record'а
    #33510265
4321
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
таки это баг 7.3.4
проверяем:
[src]CREATE OR REPLACE FUNCTION f_test_distinct()
RETURNS SETOF bool AS
'
declare
_res bool;
_tmp int4;
_tmp1 int4;
begin
_res := 1 IS DISTINCT FROM 2;
RAISE NOTICE \'1 IS DISTINCT FROM 2 %\' , _res;
RETURN NEXT _res;
_res := 1 IS DISTINCT FROM 1;
RAISE NOTICE \'1 IS DISTINCT FROM 1 %\' , _res;

_tmp:=1; _tmp1:=2;
RETURN NEXT _res;
_res := _tmp IS DISTINCT FROM _tmp1;
RAISE NOTICE \'_tmp:=1 IS DISTINCT FROM _tmp1:=2 %\' , _res;

_tmp:=1; _tmp1:=1;
RETURN NEXT _res;
_res := _tmp IS DISTINCT FROM _tmp1;
RAISE NOTICE \'_tmp:=1 IS DISTINCT FROM _tmp1:=1 %\' , _res;
RETURN NEXT _res;

_tmp:=1; _tmp1:=2;
_res := ROW(_tmp,1) IS DISTINCT FROM (_tmp1,1);
RAISE NOTICE \'ROW(_tmp:=1,1) IS DISTINCT FROM ROW(_tmp1:=2,1) %\' , _res;
RETURN NEXT _res;

_res := ROW(1,1) IS DISTINCT FROM (2,2);
RAISE NOTICE \'ROW(1,1) IS DISTINCT FROM (2,2) %\' , _res;
RETURN NEXT _res;
return;
end;
'
LANGUAGE 'plpgsql' VOLATILE;SRC]
возвраты соответственно:
7.3.4.
NOTICE: 1 IS DISTINCT FROM 2 t
NOTICE: 1 IS DISTINCT FROM 1 f
NOTICE: _tmp:=1 IS DISTINCT FROM _tmp1:=2 f
NOTICE: _tmp:=1 IS DISTINCT FROM _tmp1:=1 f
NOTICE: ROW(_tmp:=1,1) IS DISTINCT FROM ROW(_tmp1:=2,1) f
NOTICE: ROW(1,1) IS DISTINCT FROM (2,2) t
8.0.1
NOTICE: 1 IS DISTINCT FROM 2 t
NOTICE: 1 IS DISTINCT FROM 1 f
NOTICE: _tmp:=1 IS DISTINCT FROM _tmp1:=2 t
NOTICE: _tmp:=1 IS DISTINCT FROM _tmp1:=1 f
NOTICE: ROW(_tmp:=1,1) IS DISTINCT FROM ROW(_tmp1:=2,1) t
NOTICE: ROW(1,1) IS DISTINCT FROM (2,2) t
...
Рейтинг: 0 / 0
Как получить все поля Record'а
    #33510269
4321
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
таки это баг 7.3.4
проверяем:
Код: plaintext
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.
CREATE OR REPLACE FUNCTION f_test_distinct()
  RETURNS SETOF bool AS
'
declare
	_res bool;
	_tmp int4;
	_tmp1 int4;
begin 
	_res := 1 IS DISTINCT FROM 2;
	RAISE NOTICE \'1 IS DISTINCT FROM  2  %\' , _res;
	RETURN NEXT _res;
	_res := 1 IS DISTINCT FROM 1;
	RAISE NOTICE \'1 IS DISTINCT FROM  1  %\' , _res;

	_tmp:=1; _tmp1:=2;
	RETURN NEXT _res;
	_res := _tmp  IS DISTINCT FROM _tmp1;
	RAISE NOTICE \'_tmp:= 1   IS DISTINCT FROM _tmp1:= 2  %\' , _res;

	_tmp:=1; _tmp1:=1;
	RETURN NEXT _res;
	_res := _tmp  IS DISTINCT FROM _tmp1;
	RAISE NOTICE \'_tmp:= 1   IS DISTINCT FROM _tmp1:= 1  %\' , _res;
	RETURN NEXT _res;

	_tmp:=1; _tmp1:=2;
	_res := ROW(_tmp,1)  IS DISTINCT FROM (_tmp1,1);
	RAISE NOTICE \'ROW(_tmp:= 1 , 1 )  IS DISTINCT FROM ROW(_tmp1:= 2 , 1 ) %\' , _res;
	RETURN NEXT _res;

	_res := ROW(1,1)  IS DISTINCT FROM (2,2);
	RAISE NOTICE \'ROW( 1 , 1 )  IS DISTINCT FROM ( 2 , 2 ) %\' , _res;
	RETURN NEXT _res;
return;
end;
'
  LANGUAGE 'plpgsql' VOLATILE;
возвраты соответственно:
7.3.4.
NOTICE: 1 IS DISTINCT FROM 2 t
NOTICE: 1 IS DISTINCT FROM 1 f
NOTICE: _tmp:=1 IS DISTINCT FROM _tmp1:=2 f
NOTICE: _tmp:=1 IS DISTINCT FROM _tmp1:=1 f
NOTICE: ROW(_tmp:=1,1) IS DISTINCT FROM ROW(_tmp1:=2,1) f
NOTICE: ROW(1,1) IS DISTINCT FROM (2,2) t
8.0.1
NOTICE: 1 IS DISTINCT FROM 2 t
NOTICE: 1 IS DISTINCT FROM 1 f
NOTICE: _tmp:=1 IS DISTINCT FROM _tmp1:=2 t
NOTICE: _tmp:=1 IS DISTINCT FROM _tmp1:=1 f
NOTICE: ROW(_tmp:=1,1) IS DISTINCT FROM ROW(_tmp1:=2,1) t
NOTICE: ROW(1,1) IS DISTINCT FROM (2,2) t
(звиняюсь за форматирование - могабыть дропнуть пост выше?)
...
Рейтинг: 0 / 0
Период между сообщениями больше года.
Как получить все поля Record'а
    #39653108
Сделай TO_JSON(record) и все сразу увидишь и поймешь.
...
Рейтинг: 0 / 0
10 сообщений из 10, страница 1 из 1
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Как получить все поля Record'а
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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