Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / PostgreSQL Новый топик    Ответить
 Perform в запрсе с With внутри функции  [new]
Kr_Yury
Member

Откуда: Киев, Украина
Сообщений: 249
Здесь foo - функция не возвращающая значений
Я для себя нашёл такое решение (то есть используется костыль в виде select count(*) into i):
do $$
declare
   i integer;
begin
    with txn as
    (update transaction
        set amount = amount * 1.1 
      where statusid = 3
      returning transactionid, amount
    ),
    ...
    select count(*) into i
    from
       (select foo(txn.transactionid, txn.amount)
          from txn) t;
end;
$$;
Выглядит не слишком кошерно, но работает. Кто-нибудь может подсказать более красивое решение?
И ещё - в документации есть такая фраза:
Для запросов WITH после PERFORM нужно поместить запрос в скобки.
Можете объяснить о чём речь? Приведите пример запроса

Сообщение было отредактировано: 13 фев 21, 22:07
13 фев 21, 22:14    [22280619]     Ответить | Цитировать Сообщить модератору
 Re: Perform в запрсе с With внутри функции  [new]
Maxim Boguk
Member

Откуда: Melbourne, Австралия
Сообщений: 4581
Kr_Yury,

PERFORM ( WITH .... ) ;
ровно как в документации написано.

Т.е. вашем случае наверное
PERFORM (
    with txn as
    (update transaction
        set amount = amount * 1.1 
      where statusid = 3
      returning transactionid, amount
    ),
    ...
    select foo(txn.transactionid, txn.amount) from txn
);



--
Maxim Boguk
лучшая поддержка PostgreSQL: dataegret.ru

Сообщение было отредактировано: 14 фев 21, 12:49
14 фев 21, 12:54    [22280741]     Ответить | Цитировать Сообщить модератору
 Re: Perform в запрсе с With внутри функции  [new]
Kr_Yury
Member

Откуда: Киев, Украина
Сообщений: 249
Maxim Boguk, во первых из документации совсем не следует, что конструкция должна быть именно такой: PERFORM ( WITH .... ) ;
Я эту фразу понял как
PERFORM foo(txn.transactionid, txn.amount) from txn
(
    with txn as
    (update transaction
        set amount = amount * 1.1 
      where statusid = 3
      returning transactionid, amount
    ),
    ...
);

Но и приведенная конструкция при использовании в Pl/Pgsql функции не работает, возвращается ошибка
"WITH clause containing a data-modifying statement must be at the top level"
15 фев 21, 12:36    [22281042]     Ответить | Цитировать Сообщить модератору
 Re: Perform в запрсе с With внутри функции  [new]
Kr_Yury
Member

Откуда: Киев, Украина
Сообщений: 249
И самое поганое с функциями, не возвращающими значение, что конструкция
    with txn as
    (update transaction
        set amount = amount * 1.1 
      where statusid = 3
      returning transactionid, amount
    ),
    ...
      tt as
       (select foo(txn.transactionid, txn.amount)
          from txn)
   ...
выполняется без ошибок, но реально вызовы foo не выполняются. По крайней мере так работает в версии 10.10

Сообщение было отредактировано: 15 фев 21, 12:36
15 фев 21, 12:43    [22281046]     Ответить | Цитировать Сообщить модератору
 Re: Perform в запрсе с With внутри функции  [new]
Maxim Boguk
Member

Откуда: Melbourne, Австралия
Сообщений: 4581
Kr_Yury
Maxim Boguk, во первых из документации совсем не следует, что конструкция должна быть именно такой: PERFORM ( WITH .... ) ;
Я эту фразу понял как[src PLSQL]


Уж сколько раз писали не читать русскую (или любую другую переводную) документацию... а только английский оригинал.
В английском все однозначно

This executes query and discards the result. Write the query the same way you would write an SQL SELECT command, but replace the initial keyword SELECT with PERFORM. For WITH queries, use PERFORM and then place the query in parentheses. (In this case, the query can only return one row.)


--
Maxim Boguk
лучшая поддержка PostgreSQL: dataegret.ru
15 фев 21, 13:08    [22281066]     Ответить | Цитировать Сообщить модератору
 Re: Perform в запрсе с With внутри функции  [new]
Maxim Boguk
Member

Откуда: Melbourne, Австралия
Сообщений: 4581
Kr_Yury,

Как ни странно тот синтаксис к которому вы пришли в итоге в первом посте - единственный рабочий на данный момент.
Я и сам не знал что PERFORM / WITH с DML - не работают в связке.

Так что вот только так как вы сделали.


--
Maxim Boguk
лучшая поддержка PostgreSQL: dataegret.ru
15 фев 21, 13:33    [22281079]     Ответить | Цитировать Сообщить модератору
Все форумы / PostgreSQL Ответить