返回表的PostgreSQL存储过程出错

时间:2013-01-27 00:45:07

标签: sql postgresql stored-procedures

我正在尝试编写一个返回表的存储过程。该过程在语法上是正确的,psql接受它,但它会引发运行时错误。

到目前为止我所拥有的:

CREATE OR REPLACE FUNCTION get_todays_appointments()
RETURNS TABLE 
(
    fname VARCHAR(32),
    lname VARCHAR(32),
    phoneno CHAR(10),
    datetime TIMESTAMP WITHOUT TIME ZONE,
    duration INTERVAL,
    caseid INTEGER
) AS $$
BEGIN
    RETURN QUERY
        SELECT
        (
            client.fname, 
            client.lname, 
            client.phoneno, 
            appointment.datetime, 
            appointment.duration, 
            photocase.caseid
        )
            FROM  (appointment NATURAL JOIN photocase NATURAL JOIN client)
            WHERE 
            (
                appointment.datetime >= current_date 
                AND appointment.datetime < current_date + 1
            );
END;
$$
LANGUAGE plpgsql;

如果我手动执行查询,它的工作方式与indended完全相同,但使用SP我总是会遇到以下错误:

  

错误:查询结构与函数结果类型不匹配   详细信息:返回的类型记录与第1列中不同的预期类型字符不匹配。   背景:PL / pgSQL函数“get_todays_appointments”第3行在RETURN QUERY

我已经对表格架构进行了大约15次检查,但它们肯定是正确的。

奇怪的是,如果我修剪属性,那么函数工作正常,因此它一次只返回一个。一旦我尝试返回多个属性,它就会抛出错误。

我用谷歌搜索并找到了一些例子但没有任何实际效果。我也看过使用SETOF,但没有这个签名的表,所以它对我没有帮助。

我正在使用postgresql v9.1.7。

1 个答案:

答案 0 :(得分:2)

我现在没有方便的方法来测试它,但我认为你将不得不失去一些麻烦。

CREATE OR REPLACE FUNCTION get_todays_appointments()
RETURNS TABLE 
(
    fname VARCHAR(32),
    lname VARCHAR(32),
    phoneno CHAR(10),
    datetime TIMESTAMP WITHOUT TIME ZONE,
    duration INTERVAL,
    caseid INTEGER
) AS $$
BEGIN
    RETURN QUERY
        SELECT
            client.fname, 
            client.lname, 
            client.phoneno, 
            appointment.datetime, 
            appointment.duration, 
            photocase.caseid
            FROM  (appointment NATURAL JOIN photocase NATURAL JOIN client)
            WHERE 
            (
                appointment.datetime >= current_date 
                AND appointment.datetime < current_date + 1
            );
END;
$$
LANGUAGE plpgsql;

PostgreSQL的错误消息通常都很好。这个字面上是真的。

  

错误:查询结构与函数结果类型DETAIL不匹配:   返回的类型记录与预期的类型字符不匹配   第1列。语境:PL / pgSQL函数“get_todays_appointments”第3行   在RETURN QUERY

在这种情况下,RETURN QUERY返回类型为“record”的值。这是因为row constructor看起来像SELECT ROW(value1, column1, column2)。在SELECT语句中,关键字“ROW”是可选的,因此行构造函数如下所示:SELECT (value1, column1, column2)

所以这个骨架语法

select (column1, column2) from whatever 

等同于此。

select row(column1, column2) from whatever

但你不想那样。你想要的东西等同于 this

select column1, column2 from whatever

所以在列表列表中丢失那些parens。