【问题标题】:Error in PostgreSQL stored procedure that returns a table返回表的 PostgreSQL 存储过程中的错误
【发布时间】:2013-01-27 00:45:06
【问题描述】:

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

【问题讨论】:

  • 我在这里看不到任何需要使用函数的东西。您是否考虑过改用视图?
  • 这是一个学术练习。使用函数可能没有任何保证,但我应该以某种方式使用它们。既然我遇到了麻烦,我这样做可能是件好事。

标签: sql postgresql stored-procedures


【解决方案1】:

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

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 返回一个“记录”类型的值。那是因为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

所以在列列表周围丢失那些括号。

【讨论】:

  • 我永远不会抓住这个。感谢您的解释,这很有意义。我阅读了“记录”;永远不会注意到它。
  • 我只是放了一个文档链接。
  • 我猜如果我将返回类型更改为SETOF RECORD,我可以离开括号?
  • 我不确定。你为什么不试试,让我知道? :-)
  • 那个也会引发运行时错误,但从它们的外观来看,它比我以前的做法“更正确”。
猜你喜欢
  • 1970-01-01
  • 2016-10-06
  • 1970-01-01
  • 1970-01-01
  • 2021-02-01
  • 2014-05-15
  • 2017-03-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多