powered by simpleCommunicator - 2.0.59     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Результаты из функции со своим типом.
25 сообщений из 26, страница 1 из 2
Результаты из функции со своим типом.
    #39266396
AndRam
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Добрый день!
Решили перейти с Оракла на Postgre и здесь образовалась такая небольшая проблемка.

Есть тип: CREATE TYPE any_ids_table AS (any_ids_table integer[]);
Также имеется функция:
CREATE OR REPLACE FUNCTION cash_sum(atmids any_ids_table)
RETURNS SETOF cash_type_table AS ...

Как вызвать результат функции?
Пример вызова из Оракла:
select * from table(CASH_SUM(any_ids_table('100048','100045')));
...
Рейтинг: 0 / 0
Результаты из функции со своим типом.
    #39266404
Фотография vyegorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AndRamselect * from table(CASH_SUM(any_ids_table('100048','100045')));
...
Рейтинг: 0 / 0
Результаты из функции со своим типом.
    #39266407
AndRam
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
vyegorov,

ERROR: function any_ids_table(unknown, unknown) does not exist
LINE 1: select * from CASH_SUM(any_ids_table('100048','100045'));
^
HINT: No function matches the given name and argument types. You might need to add explicit type casts.
...
Рейтинг: 0 / 0
Результаты из функции со своим типом.
    #39266414
AndRam
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
AndRam,

Также
select * from CASH_SUM('100048','100045));
ERROR: unterminated quoted string at or near "'100045));"
LINE 1: select * from CASH_SUM('100048','100045));

Не получается также если прописать ARRAY.
...
Рейтинг: 0 / 0
Результаты из функции со своим типом.
    #39266431
Фотография vyegorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AndRam,

Про работу с композитными типами в доках много .

В данном случае композитный тип не нужен, ПЖ поддерживает массивы и так :

Код: sql
1.
2.
3.
4.
5.
CREATE OR REPLACE FUNCTION cash_sum(atmids int[]) RETURNS SETOF cash_type_table AS $cash_sum$
...

SELECT * FROM cash_sum(ARRAY[ 100048, 100045 ]);
SELECT * FROM cash_sum('{100048, 100045}'::int[]);
...
Рейтинг: 0 / 0
Результаты из функции со своим типом.
    #39266437
AndRam
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
vyegorov,

vyegorov,

ERROR: function cash_sum(integer[]) does not exist
LINE 1: SELECT * FROM cash_sum('{100048, 100045}'::int[]);
^
HINT: No function matches the given name and argument types. You might need to add explicit type casts.
...
Рейтинг: 0 / 0
Результаты из функции со своим типом.
    #39266446
AndRam
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
vyegorovAndRam,

Про работу с композитными типами в доках много .

В данном случае композитный тип не нужен, ПЖ поддерживает массивы и так :

Код: sql
1.
2.
3.
4.
5.
CREATE OR REPLACE FUNCTION cash_sum(atmids int[]) RETURNS SETOF cash_type_table AS $cash_sum$
...

SELECT * FROM cash_sum(ARRAY[ 100048, 100045 ]);
SELECT * FROM cash_sum('{100048, 100045}'::int[]);



У нас в Оракле просто практически вся система сделана через композитные типы.
Не хотелось бы от них избавляться - это очень много доп. работы.
...
Рейтинг: 0 / 0
Результаты из функции со своим типом.
    #39266450
qwwq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: sql
1.
select * from CASH_SUM(ARRAY[100048::bigint,100045]::any_ids_table)



и да , композит -- это композит [row|record]. а array -- это array. не надо путать одно с другим.
...
Рейтинг: 0 / 0
Результаты из функции со своим типом.
    #39266454
Фотография vyegorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AndRam,

Композитный тип не есть массив, так что я бы рассмотрел вариант сделать всё как следует.

Вам надо выбрать значение нужного типа (`SELECT ...`), а потом уже выражение `...` подставить в вызов функции "как есть".

У меня это работает:
Код: sql
1.
2.
CREATE TYPE any_ids_table AS (any_ids_table integer[]);
SELECT (ROW(ARRAY[ 100048, 100045 ]))::any_ids_table;


Соответственно:
Код: sql
1.
SELECT * FROM cash_sum( (ROW(ARRAY[ 100048, 100045 ]))::any_ids_table );
...
Рейтинг: 0 / 0
Результаты из функции со своим типом.
    #39266465
AndRam
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
vyegorovAndRam,

Композитный тип не есть массив, так что я бы рассмотрел вариант сделать всё как следует.

Вам надо выбрать значение нужного типа (`SELECT ...`), а потом уже выражение `...` подставить в вызов функции "как есть".

У меня это работает:
Код: sql
1.
2.
CREATE TYPE any_ids_table AS (any_ids_table integer[]);
SELECT (ROW(ARRAY[ 100048, 100045 ]))::any_ids_table;


Соответственно:
Код: sql
1.
SELECT * FROM cash_sum( (ROW(ARRAY[ 100048, 100045 ]))::any_ids_table );



Спасибо! Кажется заработало.
...
Рейтинг: 0 / 0
Результаты из функции со своим типом.
    #39267191
AndRam
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Добрый день!

Теперь проблема как запихать в функции переданный тип в запрос:

CREATE OR REPLACE FUNCTION cash_sum (atmids any_ids_table)
RETURNS SETOF CASH_TYPE_TABLE AS $body$
BEGIN
RETURN QUERY
SELECT sum(v.cash) AS cash , 0, get_currency_id(v.dic_currency__id)
FROM (
SELECT *
FROM ...
WHERE t.atm__id in (select atmids)
)
GROUP BY v.dic_currency__id;
END;
$body$
LANGUAGE PLPGSQL;

В данном примере выдает:
ERROR: operator does not exist: bigint = any_ids_table
LINE 10: AND t.atm__id in (select atmids)
...
Рейтинг: 0 / 0
Результаты из функции со своим типом.
    #39267213
Фотография vyegorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AndRam,

Вот первая мысль — сначала мучаетесь, как бы это всё так свернуть, чтобы функцию вызвать.
Теперь мучаетесь, как бы развернуть это всё обратно.
И всё ради того, чтобы "поменьше кода править".

Мне кажется, что-то это странный подход...
...
Рейтинг: 0 / 0
Результаты из функции со своим типом.
    #39267219
AndRam
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Так читабельнее будет:
AndRamCREATE OR REPLACE FUNCTION cash_sum (atmids any_ids_table)
RETURNS SETOF CASH_TYPE_TABLE AS $body$
BEGIN
RETURN QUERY
SELECT sum(cash) AS cash , 0, get_currency_id(dic_currency__id)
FROM atm
WHERE atm__id in (select atmids)
GROUP BY dic_currency__id;
END;
$body$
LANGUAGE PLPGSQL;


Так же еще вопросы:
Есть ли какая-нибудь подробная документация по использованию композитных табличных типов и какие команды при этом используются, типа FIRST, LAST и т.д.
...
Рейтинг: 0 / 0
Результаты из функции со своим типом.
    #39267222
Фотография vyegorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AndRam,

По существу:
т.к. вы только запрос вызываете, то вам не нужен plpgsql, тут функции на sql будет достаточно. sql предпочтительней, т.к. планировщик его "видит" и может оптимизировать, любой другой PL -- чёрный ящик

конструкции ANY / ALL / SOME в ПЖ заточены под массивы, попробуйте что-то вроде: WHERE t.atm__id = ANY ( ($1).any_ids_table ) -- вам надо обратиться к колонке в записи, коей является сложный тип.
...
Рейтинг: 0 / 0
Результаты из функции со своим типом.
    #39267229
AndRam
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
vyegorovAndRam,

Вот первая мысль — сначала мучаетесь, как бы это всё так свернуть, чтобы функцию вызвать.
Теперь мучаетесь, как бы развернуть это всё обратно.
И всё ради того, чтобы "поменьше кода править".

Мне кажется, что-то это странный подход...

Конечно это извращение, но альтернатива намного хуже. Подобных функций очень много и они используются и внутри кода и при вызове из приложения и в отчетах. Практически весь код в Oracle идет через подобные типы и внутри идет пошаговая обработка внутри типа, поэтому переделывать их неохота. К тому же хотелось бы знать работу postgre с подобными типами.
...
Рейтинг: 0 / 0
Результаты из функции со своим типом.
    #39267233
Jonhson
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AndRamДобрый день!
Решили перейти с Оракла на Postgre и здесь образовалась тa...

Сочувствую, мы тоже рассматривали перевод части функционала, но выяснилось, что мороки пока что больше, чем плюсов.

Решили подождать 10-ю версию в надежде, что п-г несколько повзрослеет
...
Рейтинг: 0 / 0
Результаты из функции со своим типом.
    #39267238
qwwq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
JonhsonAndRamДобрый день!
Решили перейти с Оракла на Postgre и здесь образовалась тa...

Сочувствую, мы тоже рассматривали перевод части функционала, но выяснилось, что мороки пока что больше, чем плюсов.

Решили подождать 10-ю версию в надежде, что п-г несколько повзрослеет
ф топег приглашаедся г--н Лавров со своим бессмертным мемом
...
Рейтинг: 0 / 0
Результаты из функции со своим типом.
    #39267241
AndRam
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
qwwqJonhsonпропущено...


Сочувствую, мы тоже рассматривали перевод части функционала, но выяснилось, что мороки пока что больше, чем плюсов.

Решили подождать 10-ю версию в надежде, что п-г несколько повзрослеет
ф топег приглашаедся г--н Лавров со своим бессмертным мемом

Проблема в том что если не перейдем с оракла на постгре заказчик откажется от программы. :(
...
Рейтинг: 0 / 0
Результаты из функции со своим типом.
    #39267247
AndRam
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
vyegorovAndRam,

По существу:
т.к. вы только запрос вызываете, то вам не нужен plpgsql, тут функции на sql будет достаточно. sql предпочтительней, т.к. планировщик его "видит" и может оптимизировать, любой другой PL -- чёрный ящик

конструкции ANY / ALL / SOME в ПЖ заточены под массивы, попробуйте что-то вроде: WHERE t.atm__id = ANY ( ($1).any_ids_table ) -- вам надо обратиться к колонке в записи, коей является сложный тип.


1)
CREATE TYPE cash_type_table AS
(cash_type_table cash_type[]);
CREATE TYPE cash_type AS
(cash_sum bigint,
cash_sum2 bigint,
dic_currency__id bigint);
CREATE TYPE any_ids_table AS
(any_ids_table integer[]);

2)
CREATE OR REPLACE FUNCTION cash_sum3(atmids any_ids_table)
RETURNS SETOF CASH_TYPE_TABLE AS $body$
BEGIN
RETURN QUERY
SELECT 1,2,3
FROM atm
WHERE id = ANY ( ($1).any_ids_table );
END;
$body$
LANGUAGE PLPGSQL;

3) SELECT * FROM cash_sum3( (ROW(ARRAY[ 100048, 100045 ]))::any_ids_table );

4) В результате такая ошибка.
ERROR: structure of query does not match function result type
DETAIL: Returned type integer does not match expected type cash_type[] in column 1.
CONTEXT: PL/pgSQL function cash_sum3(any_ids_table) line 3 at RETURN QUERY

********** Ошибка **********

ERROR: structure of query does not match function result type
SQL-состояние: 42804
Подробности: Returned type integer does not match expected type cash_type[] in column 1.
Контекст: PL/pgSQL function cash_sum3(any_ids_table) line 3 at RETURN QUERY
...
Рейтинг: 0 / 0
Результаты из функции со своим типом.
    #39267253
qwwq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AndRamqwwqпропущено...

ф топег приглашаедся г--н Лавров со своим бессмертным мемом

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

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

пж очень демократичен к экспериментам, тут не надо штатом ДБА его обследовать после каждой 600.

имхо -- везде, где можно обойтись простыми типами , вместо унаследованных -- надо обходиться простыми. везде , где можно уйти от наследства сракела -- надо от него уходить.

у вас и без этого будет полно проблем с другим устройством сейвпойнтов, отсутствием внутренних коммитов, эмуляцией автономий и прочими нехорошими привычками, типа strict для каждого select into. (вместо if FOUND then ).

и вообще -- у пж масса своих проблем, чтобы тащить в него унаследованные проблемы сшивки старого овнокода.
...
Рейтинг: 0 / 0
Результаты из функции со своим типом.
    #39267261
qwwq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AndRamvyegorovAndRam,

По существу:
т.к. вы только запрос вызываете, то вам не нужен plpgsql, тут функции на sql будет достаточно. sql предпочтительней, т.к. планировщик его "видит" и может оптимизировать, любой другой PL -- чёрный ящик

конструкции ANY / ALL / SOME в ПЖ заточены под массивы, попробуйте что-то вроде: WHERE t.atm__id = ANY ( ($1).any_ids_table ) -- вам надо обратиться к колонке в записи, коей является сложный тип.


1)

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
CREATE TYPE cash_type AS
   (cash_sum bigint,
    cash_sum2 bigint,
    dic_currency__id bigint);

2) 
CREATE OR REPLACE FUNCTION cash_sum3(atmids bigint[])
	RETURNS SETOF CASH_TYPE AS 
$body$
	SELECT 1,2,3
	FROM atm
	WHERE id = ANY ( $1 );
$body$
LANGUAGE SQL;

3) 
SELECT * FROM cash_sum3( ARRAY[ 100048::bigint, 100045 ] );
...
Рейтинг: 0 / 0
Результаты из функции со своим типом.
    #39267356
Jonhson
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AndRamqwwqпропущено...

ф топег приглашаедся г--н Лавров со своим бессмертным мемом

Проблема в том что если не перейдем с оракла на постгре заказчик откажется от программы. :(

ну у нас не так жёстко, поэтому пока мы посмотрим, так скажем

а там авось допилят и п-г до чего-то приличного.
...
Рейтинг: 0 / 0
Результаты из функции со своим типом.
    #39267363
Фотография vyegorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Jonhsonа там авось допилят и п-г до чего-то приличного.
Не допилят. PostgreSQL развивается без оглядки на другие СУБД.
...
Рейтинг: 0 / 0
Результаты из функции со своим типом.
    #39267370
Jonhson
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vyegorovJonhsonа там авось допилят и п-г до чего-то приличного.
Не допилят. PostgreSQL развивается без оглядки на другие СУБД.

если так, то перспектив вылезти на жирных заказчиков у него мало... жаль. Мне нравится эта субд и чувствую в ней перспективу
...
Рейтинг: 0 / 0
Результаты из функции со своим типом.
    #39267724
AndRam
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
qwwqAndRamпропущено...


1)

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
CREATE TYPE cash_type AS
   (cash_sum bigint,
    cash_sum2 bigint,
    dic_currency__id bigint);

2) 
CREATE OR REPLACE FUNCTION cash_sum3(atmids bigint[])
	RETURNS SETOF CASH_TYPE AS 
$body$
	SELECT 1,2,3
	FROM atm
	WHERE id = ANY ( $1 );
$body$
LANGUAGE SQL;

3) 
SELECT * FROM cash_sum3( ARRAY[ 100048::bigint, 100045 ] );




Не работает. При создании функции ошибка:

ERROR: return type mismatch in function declared to return cash_type
DETAIL: Final statement returns integer instead of bigint at column 1.
CONTEXT: SQL function "cash_sum3"

********** Ошибка **********

ERROR: return type mismatch in function declared to return cash_type
SQL-состояние: 42P13
Подробности: Final statement returns integer instead of bigint at column 1.
Контекст: SQL function "cash_sum3"
...
Рейтинг: 0 / 0
25 сообщений из 26, страница 1 из 2
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Результаты из функции со своим типом.
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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