Как вернуть конструктор строки из функции PL / pgSQL? - PullRequest
0 голосов
/ 31 мая 2018

Я пытаюсь вернуть конструктор строки из функции PL / pgSQL, но происходит сбой со следующей ошибкой: Возвращенная запись типа не соответствует ожидаемому целому числу типа в столбце 1

Вот упрощенная версия спростая функция SQL в качестве сравнения.Функция SQL работает нормально, функция PL / pgSQL выдает следующую ошибку.Что мне здесь не хватает?

Функции тестирования

CREATE FUNCTION test_sql()
RETURNS TABLE (
    a int,
    b int
)
LANGUAGE SQL
IMMUTABLE
AS $$
    SELECT (1, 1);
$$;

CREATE FUNCTION test_plpgsql()
RETURNS TABLE (
    a int,
    b int
)
LANGUAGE plpgsql
IMMUTABLE
AS $$
BEGIN
    RETURN QUERY SELECT (1, 1);
END;
$$;

SELECT * FROM test_sql();     -- OK
SELECT * FROM test_plpgsql(); --error

Сообщение об ошибке

[42804] ERROR: structure of query does not match function result type
Detail: Returned type record does not match expected type integer in column 1.
Where: PL/pgSQL function test_plpgsql() line 3 at RETURN QUERY

Ответы [ 3 ]

0 голосов
/ 31 мая 2018

На самом деле обе функции неверны.SELECT (1, 1) выбирает строку из одного столбца типа record , а не двух столбцов типа integer.

По какой-то причине это может быть неявно приведено в функцию SQL.Но изменив его на SELECT 1, 1 в обеих функциях, вы получите то, что вы хотите для обеих.

0 голосов
/ 31 мая 2018

Я вижу две проблемы в вашем дизайне:

  1. это SRF (Set Returning Function), и в этом случае это бесполезно.
  2. Вы используете SELECT дляпостоянный, он тоже бесполезен - и он медленнее:
postgres=# CREATE OR REPLACE FUNCTION test_plpgsql(OUT a int, OUT b int)
AS $$
BEGIN
  a := 1; b := 1;
END;
$$ LANGUAGE plpgsql IMMUTABLE;
CREATE FUNCTION

postgres=# SELECT * FROM test_plpgsql();
┌───┬───┐
│ a │ b │
╞═══╪═══╡
│ 1 │ 1 │
└───┴───┘
(1 row)
0 голосов
/ 31 мая 2018

Используйте обычный запрос (возвращая столбцы, а не кортеж) в RETURN QUERY:

CREATE OR REPLACE FUNCTION test_plpgsql()
RETURNS TABLE (
    a int,
    b int
)
LANGUAGE plpgsql
IMMUTABLE
AS $$
BEGIN
    RETURN QUERY SELECT 1, 1;
END;
$$;
...