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 ответа:
Хотя ответ 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 может возвращать только одно значение на запись. Что невозможно на примере вашего профсоюза. Поэтому я преобразовал его в производное табличное / встроенное представление, что и происходит с примером функции.