为什么在PostgreSQL中使用SETOF的奇怪行为?

时间:2014-11-06 10:28:50

标签: database postgresql postgresql-9.3

我有以下代码片段{CODE#1,CODE#2,CODE#3}在我的数据库中。

代码#1 :创建表“Class_Type”的语句,类似于“JAVA中的ENUM”。

它包含一些数据{“class-A”,“class-B”,“sports-A”,“RED”,“BLUE”,.....}

现在我尝试使用 CODE#2 CODE#3 的存储过程来获取这些值。

CODE#2和CODE#3的预期输出:

{

           |  classtype character varying |

           |   class-A          |

           |   class-B          |

           |   sports-A         |

           |   RED              |

           |   BLUE             |

           |    .......         |

}

What did i find Strange?

CODE#2 会多次返回预期输出,有时会返回“意外输出”。背后的原因是什么?

代码#3 工作正常,每次都会产生预期的输出。

CODE#2的意外输出:

{

       |  get_class_type_list character varying |

       |   class-A          |

       |   class-B          |

       |   sports-A        |

       |   RED                 |

       |   BLUE              |

       |    .......                |

}

以下是代码段:

CODE#1

 {

                  CREATE TABLE test.class_type
                 (
                     value character varying(80) NOT NULL,
                     is_active boolean NOT NULL DEFAULT true,
                    sort_order integer,
                    CONSTRAINT class_type_pkey PRIMARY KEY (value)
                 )
                 WITH (
                  OIDS=FALSE
                );

}

CODE#2

 {
                  CREATE OR REPLACE FUNCTION test.get_class_type_list()
                      RETURNS  SETOF character varying AS
                 $BODY$
                 DECLARE
                        SQL VARCHAR;
                    BEGIN
                         RETURN QUERY
                                (SELECT value AS "classType"
                                FROM TEST.CLASS_TYPE);
                   END;
              $BODY$
               LANGUAGE plpgsql VOLATILE
               COST 100
               ROWS 1000;

}

代码#3

{
             CREATE OR REPLACE FUNCTION test.get_class_type_list()
                RETURNS TABLE(classType character varying) AS
            $BODY$
            DECLARE
                     SQL VARCHAR;
              BEGIN
                   RETURN QUERY
                     (SELECT value AS "classType"
                      FROM TEST.CLASS_TYPE);

              END;
                $BODY$
             LANGUAGE plpgsql VOLATILE
             COST 100
             ROWS 1000;

 } 

SQL Fiddle Sample Code

Edited:

我希望Return Function的列名称为“classType”,但不是函数名。

1 个答案:

答案 0 :(得分:0)

我在结果中看到的唯一区别是列名(实际上是别名)。您可以在调用上下文中完全控制列别名:sqlfiddle(原因,有时它的行为有所不同,这是因为RETURNS SETOF <primitive-type>是一个特殊的返回子句。)

经验法则是,如果函数定义中有别名(如OUT参数,RETURNS TABLE&amp; RETURNS SETOF <composite/row-type>;但不在函数体本身中),postgresql将使用它,除非有明确的别名。如果您使用RETURNS SETOF <primitive/simple-type>而没有OUT参数,则默认别名是该列的函数名称。

注意:我第一次没有将此作为答案发布的原因,是因为遗憾的是,我在文档中找不到任何参考资料。