2012-07-13 180 views
9

在PostgreSQL 8.4中有一个存储过程调用另一个存储过程,具体取决于作为参数传入的整数值。这些存储过程被调用,它们应该返回一个整数列的关系。我遇到的问题是外部存储过程总是返回一个具有正确行数的关系,但所有的id都是NULL。PostgreSQL存储过程与RETURNS TABLE(ID整数)返回所有NULL

这里是存储过程减少到最简单的形式:

CREATE OR REPLACE FUNCTION spa(count integer) 
RETURNS TABLE (id integer) AS $$ 
BEGIN 
    RETURN QUERY SELECT generate_series(1, count); 
END; 
$$ LANGUAGE plpgsql; 

CREATE OR REPLACE FUNCTION spb(count integer) 
RETURNS TABLE (id integer) AS $$ 
BEGIN 
    RETURN QUERY SELECT generate_series(1, count); 
END; 
$$ LANGUAGE plpgsql; 

CREATE OR REPLACE FUNCTION conditional_relation_return(objectType integer, count integer) 
RETURNS TABLE (id integer) AS $$ 
BEGIN 
    IF objectType = 1 THEN 
     RETURN QUERY SELECT id FROM spa(count); 
    ELSIF objectType = 2 OR objectType = 3 THEN 
     RETURN QUERY SELECT id FROM spb(count); 
    END IF; 

END; 
$$ LANGUAGE plpgsql; 

如果你把它叫做:

# select * from conditional_relation_return(1, 2); 
id 
---- 


(2 rows) 

或者更具体地说:

# select count(*) from conditional_relation_return(1, 2) where id is null; 
count 
------- 
    2 
(1 row) 

但是,如果你打电话其中一个引用的存储过程,您会得到正确的结果:

# select * from spa(2); 
id 
---- 
    1 
    2 
(2 rows) 

那么为什么conditional_relation_return返回所有NULL?

回答

13

spa的id与输出参数ID(RETURNS TABLE (id integer))冲突。 Postgresql 8.4不会抱怨,它会从out参数id中选择id而不是saner(spa的id)。

PostgreSQL的9.1的抱怨您的原始代码:

ERROR: column reference "id" is ambiguous 
LINE 1: SELECT id FROM spa(count) 
      ^
DETAIL: It could refer to either a PL/pgSQL variable or a table column. 
QUERY: SELECT id FROM spa(count) 
CONTEXT: PL/pgSQL function "conditional_relation_return" line 4 at RETURN QUERY 

为了解决这个问题,完全符合您的查询的ID:

CREATE OR REPLACE FUNCTION conditional_relation_return(
    objectType integer, count integer) 
RETURNS TABLE (id integer) AS $$ 
BEGIN 
    IF objectType = 1 THEN 
     RETURN QUERY SELECT x.id FROM spa(count) as x; 
    ELSIF objectType = 2 OR objectType = 3 THEN 
     RETURN QUERY SELECT x.id FROM spb(count) as x; 
    END IF; 

END; 
$$ LANGUAGE plpgsql; 

输出:

test=# select * from conditional_relation_return(1, 2); 
id 
---- 
    1 
    2 
(2 rows) 

Postgresql支持列名y ou可以从你的RETURNS TABLE中选择。它仍然插入x.idRETURNS TABLEid。因此,即使您决定重命名您的RETURNS TABLE返回列的名称,它仍会将x.id插入该名称,例如。

CREATE OR REPLACE FUNCTION conditional_relation_return(
    objectType integer, count integer) 
RETURNS TABLE (hahah integer) AS $$ 
BEGIN 
    IF objectType = 1 THEN 
     RETURN QUERY SELECT x.id FROM spa(count) as x; 
    ELSIF objectType = 2 OR objectType = 3 THEN 
     RETURN QUERY SELECT x.id FROM spb(count) as x; 
    END IF; 

END; 
$$ LANGUAGE plpgsql; 

输出:

test=# select * from conditional_relation_return(1, 2); 
hahah 
------- 
    1 
    2 
(2 rows) 

通知的hahah

+0

多么滑稽。你是对的。 8.4默默吞下模糊的id错误。谢谢! – drsnyder 2012-07-14 21:41:33