【问题标题】:make_date function does not exist in plpgsqlplpgsql 中不存在 make_date 函数
【发布时间】:2021-03-16 09:32:45
【问题描述】:

我有一个 plpgsql 函数。我需要从今天起 5 天取日期,然后将月份分成“五个”来确定“最后五个”的开始。问题是服务器上使用的 posgres 版本中不存在 make_date ......

create or replace function getFirstDayOfFive()
returns timestamp with time zone as $$
declare
    firstDay timestamp;
    startOp timestamp;
begin
startOp = now() - interval '5 day';
SELECT
    make_date(
        date_part('year', startOp)::int,
        date_part('month', startOp)::int,
        greatest(
            floor(date_part('day', startOp) / 5) * 5,
            1
        )::int
    )
INTO firstDay;

RETURN firstDay;
    
end;

$$
language plpgsql;

上周运行良好,但现在调用时出现错误

ERROR: BŁĄD:  function make_date(integer, integer, integer) does not exist
LINE 2:     make_date(
            ^
HINT:  There is no function matching provided name and arguments. Maybe you should cast data.
QUERY:  SELECT
    make_date(
        date_part('year', startOp)::int,
        date_part('month', startOp)::int,
        greatest(
            floor(date_part('day', startOp) / 5) * 5,
            1
        )::int
    )
CONTEXT:  PL/pgSQL function "getfirstdayoffive" line 7 at wyrażenie SQL


SQL state: 42883

发生了什么,之前它工作了,现在却报错了?

[编辑] 我发现 make_date 可从 postgresQL 9.4 获得,但在服务器上有 posthresQL 9.1 有没有办法在这个旧版本的 od DB 中做同样的事情?我正在尝试用类似的东西替换 make_date

create or replace function getFirstDayOfFive()
returns timestamp with time zone as $$
declare
    firstDay timestamp;
    startOp timestamp;
begin
startOp = now() - interval '5 day';
SELECT
    date to_char(startOp, 'YYYY-MM-')||to_char(greatest(
            floor(date_part('day', startOp) / 5) * 5,
            1
        )::int)
INTO firstDay;
RETURN firstDay;  
end;
$$
language plpgsql;

【问题讨论】:

  • 为我工作:dbfiddle.uk/… 你能试着用小提琴来证明你的问题吗?
  • 你是在上周的不同服务器/安装上运行它吗?
  • 不,我在与上周在同一台服务器上的同一台计算机上运行它。唯一改变的是我现在使用 VPN,因为我在远程工作
  • 我在公司的朋友在我们的网络上运行它并得到与我相同的错误。我们正在使用 pgAdmin 4
  • 与您的问题无关,但是:Postgres 9.1 和 9.4 都不再是 supported - 您应该尽快计划升级。

标签: postgresql datetime plpgsql


【解决方案1】:

我认为您可以通过在月初添加所需的天数来简化此操作。显然你只想要一个date,所以我还建议将返回类型更改为date

create or replace function getfirstdayoffive()
returns date
as
$$
   select date_trunc('month', current_date - 5)::date 
          + (greatest(floor(extract(day from current_date - 5) / 5) * 5, 1))::int - 1;
$$    
language sql
stable;

【讨论】:

  • 其实我需要一个varchar,不过没关系:)我试试这个,谢谢
  • @mario:为什么?您应该仅将日期值转换为 varchar 以用于显示目的,仅此而已。但是您始终可以使用to_char()date 转换为格式化的varchar
  • 因为我在后端使用了这个函数的结果,并且日期是一个字符串(一些具有旧结构的旧项目)
猜你喜欢
  • 2017-10-19
  • 1970-01-01
  • 1970-01-01
  • 2012-03-26
  • 1970-01-01
  • 2013-02-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多