PostgreSQL procédure stockée avec table RETURNS (ID entier) retournant tous les NULLs

j'ai une procédure stockée dans PostgreSQL 8.4 qui appelle une autre procédure stockée en fonction de la valeur entière transmise comme paramètre. Ces procédures stockées sont appelées telles qu'elles doivent retourner une relation avec une colonne entière. Le problème que j'ai est que la procédure stockée externe renvoie toujours une relation avec le nombre correct de lignes mais avec tous les id'S NULL.

Voici la procédure stockée réduit à sa plus simple forme:

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;

Et si vous l'appelez:

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


(2 rows)

ou plus spécifiquement:

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

mais si vous appelez l'une des procédures stockées référencées, vous obtenez les bons résultats:

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

alors pourquoi conditional_relation_return renvoie-t-il tous les Nuls?

9
demandé sur drsnyder 2012-07-14 03:24:06

1 réponses

id des conflits spa avec le paramètre out id (RETURNS TABLE (id integer)). Postgresql 8.4 ne se plaint pas, il choisit id à partir du paramètre out id au lieu du plus propre(id de spa).

Postgresql 9.1 de se plaindre de votre code 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

Pour le fixer, obtenir l'id de votre requête:

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;

Sortie:

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

Postgresql honore le(S) nom (s) de colonne que vous choisissez dans votre RETURNS TABLE. - Il encore de la fente x.idid de votre RETURNS TABLE. Donc, même vous avez décidé de renommer votre RETURNS TABLE le nom de la colonne de retour, il sera toujours la fente x.id à ce nom, par exemple,

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;

Sortie:

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

Notez le hahah colonne

13
répondu Michael Buen 2012-07-14 11:54:30