2

我在使用 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. 调用测试工具

意外返回如下所示的错误 ERROR: invalid input syntax for integer: "(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
4

2 回答 2

1

我以前没见过RETURNS tablename语法。我个人会使用RETURNS RECORDor 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)
于 2011-08-15T07:55:21.497 回答
0

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

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

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

于 2013-09-03T10:28:32.407 回答