PostgreSQL: почему подзапросы в виде выражений не могут возвращать более одной строки, а функции могут?


Если я попытаюсь создать столбец, значение которого является select, возвращающим более одной строки, я получу ошибку.

=> select (select 1 union select 2);
ERROR:  more than one row returned by a subquery used as an expression
Но если я создаю функцию, которая делает то же самое, я получаю желаемое поведение.
=> create or replace function onetwo() returns setof integer as $$
$> select 1 union select 2 
$> $$ language 'sql' strict immutable;
CREATE FUNCTION
=> select onetwo();
 onetwo 
--------
      1
      2

В чем разница?

2 6

2 ответа:

Хотя ответ OMG Ponies полностью верен, я бы предпочел сформулировать его так: Вы путаете SELECT f() с SELECT literal.

  • SELECT f() выполняет функцию и возвращает ее результат. И функция возврата таблицы также может быть записана как SELECT * FROM f() - Что еще более элегантно. Поскольку Pg еще не имеет хранимых процедур - меньше планирования они могут быть сделаны через функции - мы используем SELECT, как Microsoft SQL использует EXECUTE

  • SELECT LITERAL является ли метод возврата a литерал (что-то, что может поместиться в строке/столбце).

Это не сравнение яблок с яблоками.

select * 
  FROM (select 1 
        union ALL 
        select 2)

... эквивалентно вашей функции.

Столбец в предложении SELECT может возвращать только одно значение на запись. Что невозможно на примере вашего профсоюза. Поэтому я преобразовал его в производное табличное / встроенное представление, что и происходит с примером функции.