我在Postgres 9.0.4上遇到意外行为,使用pl / pgsql,从一个从另一个函数中返回ROWTYPE变量的函数中选择。 在下面的例子中我:
以下显示的错误意外返回 错误:整数的输入语法无效:“(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
答案 0 :(得分:1)
之前我没见过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)
答案 1 :(得分:0)
似乎有效的方法是将testx中的select更改为以下内容:
SELECT (fn_test_get_row(1)).*
INTO i_row;
如果您考虑不使用括号和星号,则选择记录类型的一列时,错误消息是有意义的。 Postgres然后尝试将此列转换为结果的第一列类型,从而导致您提供的错误消息。