【问题标题】:How do I use a date as a variable in a postgreSQL function?如何在 postgreSQL 函数中使用日期作为变量?
【发布时间】:2016-05-23 15:35:56
【问题描述】:

我正在尝试在 postgreSQL 9.5 中编写一个以日期为参数的函数。我的表有一个名为 inception_date 的列,我希望函数返回表中 inception_date 大于作为变量提供的日期的所有行。以下是我的功能:

    CREATE OR REPLACE FUNCTION somefunc(date) RETURNS setof table AS 
    $BODY$
    DECLARE variable ALIAS FOR $1;
    BEGIN
    RETURN QUERY SELECT * FROM table WHERE inception_date > variable;
    END;
    $BODY$
    LANGUAGE 'plpgsql'; 

    SELECT somefunc('2014-07-02');

我找不到任何信息表明 posgreSQL 函数中日期的处理方式与其他数据类型不同,但此函数不显示任何输出,而查询

   SELECT * FROM table WHERE inception_date > '2014-07-02';

返回 15 行。有谁知道这里可能出了什么问题?

【问题讨论】:

  • 其实SELECT somefunc('2014-07-02');SELECT * FROM table WHERE inception_date > '2014-07-02';并不完全相同,因为当查询返回单个列时,函数返回record类型的单个列。你如何检查结果?
  • 嗯,使用“ALIAS FOR”而不是仅仅将参数名称放在函数定义中有点过时,而且您不想引用“plpgsql”语言规范,但这看起来应该可以工作。有些事情不像看起来那样。首先使用“SELECT * FROM somefunc ...”正确调用它。然后,通过 (1) 只返回整个表然后 (2) 显式检查常量日期来简化。告诉我们这是做什么的。
  • inception_date是什么类型的?

标签: sql postgresql function datetime


【解决方案1】:

这里发生了什么,您对代码的解释与 PostgreSQL 解析器不同。 For You '2014-07-02' 是一个日期。对于解析器,这是一个字符串。但他试图表现得很好,当它看到你用它来过滤日期列时,它试图将其解释为日期。

但是给定“2014-07-02”,您是指 2 月 7 日还是 7 月 2 日?他不知道(我也不知道)。所以,基本上这是你这边的错误,你不应该这样做。

我的建议是使用日期类型的命名参数创建函数,并将其用作日期。然后,当调用这个函数并以字符串作为参数时,我会将这个字符串转换为日期,告诉 PostgreSQL 我的意思。

下面的示例和参考手册。

    CREATE OR REPLACE FUNCTION somefunc(p_date date)
    RETURNS setof table 
    AS 
    $BODY$
        BEGIN
            RETURN QUERY SELECT * FROM table WHERE inception_date > p_date;
        END;
    $BODY$
    LANGUAGE 'plpgsql'; 

    SELECT somefunc(to_date('2014-07-02','YYYY-MM-DD'));

在这里您可以找到有关date formattingcreating of functions 的更多信息。

【讨论】:

    【解决方案2】:

    我有这个“模式”来使用包含日期的伪变量。它不依赖于函数。 我喜欢为此目的使用 WITH() CTE:

    WITH myvar (enddate) AS (VALUES(to_date('2020-06-26', 'YYYY-MM-DD')))
    SELECT 'Total downloaded records', sum(d.total_records) FROM download_table d 
    JOIN myvar m ON date(d.created) BETWEEN '2020-01-01' AND m.enddate
    

    请注意 WITH 公用表表达式包含转换为日期格式的日期。您需要这个,因为您需要比较日期类型而不是日期

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-12-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-16
      • 1970-01-01
      相关资源
      最近更新 更多