【问题标题】:Postgres 9.0.4 : Error calling function which returns a ROWTYPE from within another functionPostgres 9.0.4:调用从另一个函数中返回 ROWTYPE 的函数时出错
【发布时间】:2026-01-30 19:20:08
【问题描述】:

我在使用 pl/pgsql 的 Postgres 9.0.4 上遇到了与从另一个函数中返回 ROWTYPE 到 ROWTYPE 变量的函数中进行选择有关的意外行为。 在下面的例子中我:

  1. 创建表 TESTTABLE 并插入一行。
  2. 创建一个函数 FN_TEST_GET_ROW,该函数根据从 TESTTABLE 中选择的单行返回 ROWTYPE TESTTABLE 行
  3. 以函数 TESTX 的形式创建一个测试工具,该函数调用 ID=1 的 FN_TEST_GET_ROW
  4. 调用测试工具

意外返回如下所示的错误 错误:整数的无效输入语法:“(1,Fred)”

我只希望返回值 (1, Fred),如果我执行会发生这种情况

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

【问题讨论】:

  • 抱歉,这有点搞砸了。应阅读:添加数据 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;返回 i_row;结尾; $$ 语言 plpgsql;创建测试函数 CREATE OR REPLACE FUNCTION testx() RETURNS testtable AS $$ DECLARE i_row testtable;开始选择 fn_test_get_row(1) INTO i_row;返回 i_row;结尾; $$ 语言 plpgsql;

标签: function postgresql syntax-error rowtype


【解决方案1】:

我以前没有见过RETURNS tablename 语法。我个人会使用RETURNS RECORDRETURNS 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)

【讨论】:

    【解决方案2】:

    似乎也可以将 testx 中的选择更改为以下内容:

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

    如果您认为在没有括号和星号的情况下选择了记录类型的一列,则该错误消息是有意义的。 Postgres 然后尝试将此列转换为结果的第一列类型,从而导致您给出的错误消息。

    【讨论】:

      最近更新 更多