Postgres 9.0.4: Ошибка вызова функции, которая возвращает ROWTYPE из другой функции - PullRequest
2 голосов
/ 15 августа 2011

Я испытываю неожиданное поведение на Postgres 9.0.4 при использовании pl / pgsql, касающемся выбора из функции, которая возвращает ROWTYPE в переменную ROWTYPE из другой функции.В приведенном ниже примере I:

  1. Создайте таблицу TESTTABLE и вставьте строку.
  2. Создайте функцию FN_TEST_GET_ROW, которая возвращает строку ROWTYPE TESTTABLE на основе выбора одной строки изTESTTABLE
  3. Создание тестового жгута в форме функции TESTX, которая вызывает FN_TEST_GET_ROW с ID = 1
  4. Вызов тестового жгута

Ошибка, показанная ниже, возвращаетсянеожиданно ОШИБКА: неверный синтаксис ввода для целого числа: "(1, Фред)"

Я бы просто ожидал, что будут возвращены значения (1, Фред), что и произойдет, если я выполню

SELECT fn_test_get_row(1);

напрямую.

Создать таблицу:

CREATE TABLE testtable
(
id INTEGER,
name VARCHAR(10)
);

Добавить данные:

INSERT INTO testtable (id, name) VALUES (1, 'Fred');

Создать функцию:

CREATE OR REPLACE FUNCTION fn_test_get_row(a INTEGER)
RETURNS testtable AS $$
DECLARE
i_row testtable;
BEGIN

SELECT *
INTO   i_row
FROM testtable
WHERE id = a;

-- Success
RETURN i_row;

END;
$$ LANGUAGE plpgsql;

Создать тестовую функцию:

CREATE OR REPLACE FUNCTION testx()
RETURNS testtable AS $$
DECLARE
i_row testtable;
BEGIN

SELECT fn_test_get_row(1)
INTO   i_row;

-- Success
RETURN i_row;
END;    
$$ LANGUAGE plpgsql;

Выполнить функцию теста:

select testx();

Ошибка вернулась:

ERROR:  invalid input syntax for integer: "(1,Fred)"
CONTEXT:  PL/pgSQL function "testx" line 8 at SQL statement

********** Error **********

ERROR: invalid input syntax for integer: "(1,Fred)"
SQL state: 22P02
Context: PL/pgSQL function "testx" line 8 at SQL statement

Ответы [ 2 ]

1 голос
/ 15 августа 2011

Я не видел синтаксис RETURNS tablename раньше. Я бы лично использовал RETURNS RECORD или RETURNS SETOF. Вот фиксированные функции для вас. Я изменил функцию testx для обработки fn_test_get_row() как таблицы и изменил тип результата fn_test_get_row() на набор.

CREATE OR REPLACE FUNCTION fn_test_get_row(a INTEGER)
RETURNS SETOF testtable AS $$
DECLARE
    i_row testtable%ROWTYPE;
BEGIN
    SELECT INTO i_row * FROM testtable WHERE id = a;
    RETURN NEXT i_row;
END;
$$ LANGUAGE plpgsql;

CREATE OR REPLACE FUNCTION testx()
RETURNS SETOF testtable AS $$
DECLARE
    i_row testtable%ROWTYPE;
BEGIN
    SELECT INTO i_row * FROM fn_test_get_row(1) AS foo;
    RETURN NEXT i_row;
END;
$$ LANGUAGE plpgsql;

Что дает:

# select testx();
  testx   
---------- 
 (1,Fred)
(1 row)
0 голосов
/ 03 сентября 2013

Что также работает, так это изменение выбора в testx на следующее:

SELECT (fn_test_get_row(1)).*
INTO   i_row;

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

...