【问题标题】:Casted timeStamp does not give correct result in PL/pgsqlCasted timeStamp 在 PL/pgsql 中没有给出正确的结果
【发布时间】:2016-10-22 23:24:18
【问题描述】:

我是 pl/pgsql 的新手,我正在尝试执行以下函数,结果是 0 条记录。

CREATE OR REPLACE FUNCTION public.detectselect (i_channelID integer,te_startTime text,te_endTime text)
RETURNS SETOF detect_inst AS $BODY$
declare
    r detect_inst%rowtype;
    tstz_endTime timestamp without time zone;
    tstz_startTime timestamp without time zone;
BEGIN
    tstz_endTime = to_timestamp(te_endTime,'DD/MM/YYYY hh24:mi:ss')::timestamp without time zone;
    tstz_startTime = to_timestamp(te_startTime,'DD/MM/YYYY hh24:mi:ss')::timestamp without time zone;
    for r in SELECT * FROM detect_inst d WHERE d."ChannelID" = i_channelID AND d."EndTime" >= tstz_startTime AND d."EndTime" < tstz_endTime loop
        return next r;
    end loop;
    RETURN;
END;
$BODY$ LANGUAGE plpgsql;

调用

select detectselect(1,'2016-01-21 0:0:0','2016-01-23 0:0:0');

但是当我以这种方式给出静态时间戳值时,它会给出正确的结果

CREATE OR REPLACE FUNCTION public.detectselect (i_channelID integer,te_startTime text,te_endTime text)
RETURNS SETOF detect_inst AS $BODY$
declare
    r detect_inst%rowtype;
    tstz_endTime timestamp without time zone;
    tstz_startTime timestamp without time zone;
BEGIN
    tstz_endTime = to_timestamp(te_endTime,'DD/MM/YYYY hh24:mi:ss')::timestamp without time zone;
    tstz_startTime = to_timestamp(te_startTime,'DD/MM/YYYY hh24:mi:ss')::timestamp without time zone;
    for r in SELECT * FROM detect_inst d WHERE d."ChannelID" = i_channelID AND d."EndTime" >= '2016-01-21 0:0:0' AND d."EndTime" < '2016-01-23 0:0:0' loop
        return next r;
    end loop;
    RETURN;
END;
$BODY$ LANGUAGE plpgsql;

【问题讨论】:

  • 你为什么把它传递为text?如果您只将参数声明为timestamp 并去掉to_timestamp(),您可以使整个函数更简单。另外:如果你使用 to_timestamp() 演员 ::timestamp 是没用的
  • 如果我将参数声明为时间戳应该如何调用函数。

标签: postgresql plpgsql


【解决方案1】:

您的功能过于复杂。您不需要 PL/pgSQL,也不需要(慢)游标来返回结果。

它可以简化为一个普通的 SQL 函数,这也会更快:

CREATE OR REPLACE FUNCTION public.detectselect (i_channelID integer, te_startTime timestamp, te_endTime timestamp)
   RETURNS SETOF detect_inst AS 
$BODY$
    SELECT * 
    FROM detect_inst d 
    WHERE d."ChannelID" = i_channelID 
    AND d."EndTime" >= te_starttime
    AND d."EndTime" < te_endtime
$BODY$ 
LANGUAGE sql;

然后调用它:

select * 
from detectselect(1, timestamp '2016-01-21 00:00:00', timestamp '2016-01-23 00:00:00' );

你也应该避免那些可怕的带引号的标识符。他们比他们值得的麻烦更多

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-05-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-01
    相关资源
    最近更新 更多