2012-07-13 9 views
9

Tengo un procedimiento almacenado en PostgreSQL 8.4 que llama a otro procedimiento almacenado según el valor entero pasado como parámetro. Esos procedimientos almacenados se denominan de forma que devuelvan una relación con una columna entera. El problema que estoy teniendo es que el procedimiento almacenado externo siempre devuelve una relación con el número correcto de filas, pero con todas las identificaciones NULL.Procedimiento almacenado de PostgreSQL con RETURNS TABLE (entero de identificación) que devuelve todos los NULL

Aquí está el procedimiento almacenado reducido a su forma más simple:

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; 

Y si lo llaman:

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


(2 rows) 

O más concretamente:

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

Pero si llamas uno de los procedimientos almacenados a los que se hace referencia, obtendrá los resultados correctos:

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

¿Por qué conditional_relation_return devuelve todos los valores NULL?

Respuesta

13

El id de spa entra en conflicto con el id del parámetro out (RETURNS TABLE (id integer)). Postgresql 8.4 no se queja, elige id desde el id de parámetro en lugar de id (id de spa).

PostgreSQL 9.1 de queja en su código original:

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 

solucionarlo, totalmente calificar el id en su consulta:

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; 

Salida:

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

Postgresql hace honor al nombre de la columna (s) y o elija de su RETURNS TABLE. Todavía ranura x.id al id de su RETURNS TABLE. Por lo tanto, incluso si ha decidido cambiar el nombre de la columna de devolución RETURNS TABLE, todavía se insertará el x.id en ese nombre, p.

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; 

Salida:

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

Aviso columna hahah

+0

¿Cómo divertido. Tienes razón. 8.4 se traga silenciosamente el error de identificación ambiguo. ¡Gracias! – drsnyder

Cuestiones relacionadas