这两个PostgreSQL函数等效吗?(返回表格并返回集合)

这两个PostgreSQL函数等效吗?(返回表格并返回集合),sql,postgresql,plpgsql,postgresql-8.3,Sql,Postgresql,Plpgsql,Postgresql 8.3,我同时处理两个PostgreSQL安装:我的本地环境和真正的远程服务器。遗憾的是,服务器有一个旧版本(8.3.11),而我的本地环境是更新的(9.4) 我目前没有办法更新远程服务器,因此我正在将一个在9.4中运行良好的函数(它使用返回表)转换为在8.3.11中应该可以使用的函数(它应该使用返回集) 但是,尽管本地环境函数运行良好,并提供了良好的结果,但远程环境函数始终不会产生任何结果(使用完全相同的表!) 那么,这两者完全相等吗 本地环境的更新功能: CREATE OR REPLACE FUNC

我同时处理两个PostgreSQL安装:我的本地环境和真正的远程服务器。遗憾的是,服务器有一个旧版本(8.3.11),而我的本地环境是更新的(9.4)

我目前没有办法更新远程服务器,因此我正在将一个在9.4中运行良好的函数(它使用
返回表
)转换为在8.3.11中应该可以使用的函数(它应该使用
返回集

但是,尽管本地环境函数运行良好,并提供了良好的结果,但远程环境函数始终不会产生任何结果(使用完全相同的表!)

那么,这两者完全相等吗

本地环境的更新功能:

CREATE OR REPLACE FUNCTION pra2.GetGamesOnDate(date) 
  RETURNS TABLE (game_date date, is_home varchar, is_away varchar) AS $$
BEGIN
   RETURN QUERY  
   SELECT g.game_date, p1.team_name AS plays_at_home, p2.team_name AS plays_away
   FROM pra2.game g
   JOIN pra2.team p1 ON g.is_home = p1.team_id
   JOIN pra2.team p2 ON g.is_away = p2.team_id
   WHERE g.game_date = $1;
   IF NOT FOUND THEN
      RAISE EXCEPTION 'No hay partidos para la fecha %.', $1;
   END IF;
   RETURN;
END
$$
   LANGUAGE plpgsql;
CREATE TYPE return_type AS 
(game_date date,
is_home varchar,
is_away varchar);

CREATE OR REPLACE FUNCTION pra2.GetGamesOnDate(date) 
  RETURNS SETOF return_type AS $$ 
DECLARE
   _rec return_type;
BEGIN
   RETURN QUERY  
   SELECT g.game_date, p1.team_name AS plays_at_home, p2.team_name AS plays_away
   FROM pra2.game g
   JOIN pra2.team p1 ON g.is_home = p1.team_id
   JOIN pra2.team p2 ON g.is_away = p2.team_id
   WHERE g.game_date = $1;
   IF NOT FOUND THEN
   RAISE EXCEPTION 'No hay partidos para la fecha %.', $1;
   END IF;
      RETURN next _rec;
END
$$
   LANGUAGE plpgsql;
这里是我修改后使用的函数
SETOF

CREATE OR REPLACE FUNCTION pra2.GetGamesOnDate(date) 
  RETURNS TABLE (game_date date, is_home varchar, is_away varchar) AS $$
BEGIN
   RETURN QUERY  
   SELECT g.game_date, p1.team_name AS plays_at_home, p2.team_name AS plays_away
   FROM pra2.game g
   JOIN pra2.team p1 ON g.is_home = p1.team_id
   JOIN pra2.team p2 ON g.is_away = p2.team_id
   WHERE g.game_date = $1;
   IF NOT FOUND THEN
      RAISE EXCEPTION 'No hay partidos para la fecha %.', $1;
   END IF;
   RETURN;
END
$$
   LANGUAGE plpgsql;
CREATE TYPE return_type AS 
(game_date date,
is_home varchar,
is_away varchar);

CREATE OR REPLACE FUNCTION pra2.GetGamesOnDate(date) 
  RETURNS SETOF return_type AS $$ 
DECLARE
   _rec return_type;
BEGIN
   RETURN QUERY  
   SELECT g.game_date, p1.team_name AS plays_at_home, p2.team_name AS plays_away
   FROM pra2.game g
   JOIN pra2.team p1 ON g.is_home = p1.team_id
   JOIN pra2.team p2 ON g.is_away = p2.team_id
   WHERE g.game_date = $1;
   IF NOT FOUND THEN
   RAISE EXCEPTION 'No hay partidos para la fecha %.', $1;
   END IF;
      RETURN next _rec;
END
$$
   LANGUAGE plpgsql;

它根本没有给出错误消息,运行正常,但只是不产生任何结果(它总是引发异常消息),因此我想知道在
查询集中是否有错误设置…

从文档判断,
返回查询
没有在PostgreSQL 8.3中设置
找到
。(PostgreSQL 9.1的相关文档位于;相应的语句未出现在相应的PostgreSQL 8.3文档中位于。)因此,如果未找到您的
检查并不是您想要的

老实说,我不确定在PostgreSQL 8.3中实现这一点的最佳方法是什么。一种选择是这样写:

CREATE OR REPLACE FUNCTION pra2.GetGamesOnDate(date) 
RETURNS SETOF return_type AS $$ 
DECLARE _rec return_type;
        has_rec boolean;
BEGIN
    has_rec := false;
    FOR _rec IN
        SELECT g.game_date, p1.team_name AS plays_at_home, p2.team_name AS plays_away
        FROM pra2.game g
        JOIN pra2.team p1 ON g.is_home = p1.team_id
        JOIN pra2.team p2 ON g.is_away = p2.team_id
        WHERE g.game_date = $1
    LOOP
        has_rec := true;
        RETURN NEXT _rec;
    END LOOP;
    IF NOT has_rec THEN
        RAISE EXCEPTION 'No hay partidos para la fecha %.', $1;
    END IF;
END
$$ LANGUAGE plpgsql;
(免责声明:尚未测试。)

PL/pgSQL。是的

但您仍然不必求助于更复杂、更昂贵的循环。您可以使用另一种方法
GET DIAGNOSTICS\u ct=ROW\u COUNT,在手册中找到的
旁边解释:

CREATE TYPE return_type AS ( ...);

CREATE OR REPLACE FUNCTION pra2.GetGamesOnDate(date) 
  RETURNS SETOF return_type AS
$func$ 
DECLARE
   _ct int;
BEGIN
   RETURN QUERY  
   SELECT g.game_date, p1.team_name, p2.team_name
   FROM   pra2.game g
   JOIN   pra2.team p1 ON g.is_home = p1.team_id
   JOIN   pra2.team p2 ON g.is_away = p2.team_id
   WHERE  g.game_date = $1;

   GET DIAGNOSTICS _ct = ROW_COUNT;  -- number of returned rows.

   IF _ct = 0 THEN
      RAISE EXCEPTION 'No hay partidos para la fecha %.', $1;
   END IF;
END
$func$  LANGUAGE plpgsql;
另外,变量
\u rec return\u type
return next\u rec在原始版本中没有任何用途

现在函数是等价的。你甚至可以在Postgres 9.4中使用同样的方法

密切相关的回答:


旁白:类似于
GetGamesOnDate
的驼峰大小写标识符在Postgres中是个坏主意。坚持使用合法的小写名称。

Master!它完全像你说的那样工作!我仍然会抱怨他们使用8.3。。。但至少你给了我很大的推动。我最近才开始学习postgreSQL,我是通过阅读更新版本的文档来学习的,所以这有点让人困惑。您忘记添加您提到的(逐字)错误消息。应该永远在那里。谢谢你的替代版本,我会记住你的建议!