使用if then语句创建plpgsql函数时出错

时间:2013-12-16 20:45:46

标签: sql function postgresql if-statement plpgsql

我正在尝试创建这个PostgreSQL函数:

create or replace function sp_get_user_activity(
        begindate date = null,
    enddate date = null)
returns table ( 
    page varchar(75)) as
$body$
begin
    return query
    if begindate is not null and enddate is not null then
        begin
        select page from log_pg where begindate >= created and endate <= created;
        end;
    else
        if begindate is not null then
            begin
            select page from log_pg where begindate >= la.created_on;
            end;
        end if;
        if enddate is not null then
            begin
            select page from log_pg where endate <= created;
            end;
        end if;
    end if;
end;
$body$
language plpgsql;

我想创建一个从表中获取页面名称的函数,该函数可以是开始日期和结束日期,或者只是结束日期或仅仅是开始日期。

我在尝试创建函数时得到的错误消息是指的是第一个“if”语句(我在上面剪切/粘贴的代码中的第9行)

ERROR:  syntax error at or near "if"
LINE 14:  if begindate is not null and enddate is not null then
          ^

********** Error **********

ERROR: syntax error at or near "if"
SQL state: 42601

尝试使用Google搜索错误代码,但没有运气。

2 个答案:

答案 0 :(得分:0)

您遇到以下问题:

return query        

如果你删除它会修复错误。

答案 1 :(得分:0)

CREATE OR REPLACE FUNCTION sp_get_user_activity(begindate date = null
                                               ,enddate   date = null)
RETURNS TABLE (page varchar(75)) AS
$func$
BEGIN

IF begindate IS NOT NULL AND enddate IS NOT NULL THEN
   RETURN QUERY
   SELECT l.page FROM log_pg l WHERE l.created BETWEEN begindate AND enddate;

ELSIF begindate IS NULL THEN
   RETURN QUERY
   SELECT l.page from log_pg l where l.created >= enddate;

ELSE
   RETURN QUERY
   SELECT l.page FROM log_pg l WHERE l.created <= begindate;
END IF;

END
$func$ LANGUAGE plpgsql;
  • RETURN QUERY必须后跟SELECT语句。您不能使用IF块。这是错误消息的直接原因。

  • 不要在不需要的情况下启动单独的代码块(begin .. end;)。它们会降低性能并占用交易ID。在plpgsql中几乎没有必要。

  • 简化您的逻辑。如果其中一个IS NULL,您可以简化..

  • endatecreated_on中的拼写错误。 la.created_on中的非法表格资格。

  • 必须表限定与参数名称(SELECT l.page FROM log_pg l ...)冲突的列名。您的OUT参数page在函数体中随处可见。会与列名page发生冲突。作为替代方案,您可以避免冲突的参数名称。

这个单一的SQL语句也会这样做,顺便说一下:

SELECT page FROM log_pg
WHERE (begindate >= created OR begindate IS NULL)
AND   (enddate <= created OR enddate IS NULL);

您可以将其包装到另一个plpgsql函数或一个简单的SQL函数中:

CREATE OR REPLACE FUNCTION sp_get_user_activity(begindate date = null
                                               ,enddate   date = null)
  RETURNS SETOF varchar(75) AS
$func$
SELECT page FROM log_pg
WHERE (begindate >= created OR begindate IS NULL)
AND   (enddate <= created OR enddate IS NULL)
$func$ LANGUAGE sql;

需要Postgres 9.1或更高版本。在旧版本中,您必须在SQL函数中使用位置参数($1$2)。