3

我正在尝试编写一个返回表的存储过程。该过程在语法上是正确的并且 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。

4

1 回答 1

3

我现在没有方便的方法来测试这个,但我认为你将不得不失去一些括号。

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 的错误信息通常非常好。这句话是真的。

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

在这种情况下,RETURN QUERY 返回一个“记录”类型的值。那是因为行构造函数看起来像这样,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

所以失去列列表周围的那些括号。

于 2013-01-27T01:24:49.780 回答