2012-07-13 2 views
9

PostgreSQL 8.4には、パラメータとして渡される整数値に応じて別のストアドプロシージャを呼び出すストアドプロシージャがあります。これらのストアドプロシージャは、1つの整数列との関係を返すように呼び出されます。私が抱えている問題は、外側のストアドプロシージャは、常に正しい行数の関係を返しますが、すべてのIDがNULLであるということです。ここですべてのNULLを返すRETURNS TABLE(id整数)を持つPostgreSQLストアドプロシージャ

は、その最も単純な形式に縮小ストアドプロシージャです:

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) 

しかし、あなたが呼び出す場合参照されているストアドプロシージャの1つで、正しい結果が得られます。

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

なぜ、conditional_relation_returnはすべてのNULLを返しますか?

答えて

13

spaのidは、outパラメータid(RETURNS TABLE (id integer))と競合します。 PostgreSQL 8.4は、不平を言っていないので、sanerのid(spaのid)ではなくidパラメータから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を尊重します。あなたのRETURNS TABLEから選択してください。それでもあなたのRETURNS TABLEx.ididにスロットします。したがって、返信する列の名前を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

関連する問題