Postgres 9.0.4:调用函数时出错,从另一个函数中返回一个ROWTYPE

时间:2011-08-15 06:05:39

标签: function postgresql syntax-error rowtype

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

  1. 创建一个表,TESTTABLE并插入一行。
  2. 创建一个函数FN_TEST_GET_ROW,根据从TESTTABLE中选择的一行返回一行ROWTYPE TESTTABLE
  3. 以函数TESTX的形式创建一个测试工具,调用ID = 1的FN_TEST_GET_ROW
  4. 调用测试工具
  5. 以下显示的错误意外返回 错误:整数的输入语法无效:“(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
    

2 个答案:

答案 0 :(得分: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)

答案 1 :(得分:0)

似乎有效的方法是将testx中的select更改为以下内容:

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

如果您考虑不使用括号和星号,则选择记录类型的一列时,错误消息是有意义的。 Postgres然后尝试将此列转换为结果的第一列类型,从而导致您提供的错误消息。