【问题标题】:migrate sqlserver function into postgres将 sql server 函数迁移到 postgres
【发布时间】:2021-05-26 09:21:39
【问题描述】:

我在 SQL 服务器中有一个计算到期金额的函数。 我已将数据库迁移到 Postgres,但我无法在 Postgres 中使用该功能,因为这两个数据库具有不同的架构和语法。 我是 Postgres 的新手,我不知道如何从 SQL 服务器迁移 Postgres 中的该功能。 这是函数,请帮我转换一下。

CREATE FUNCTION "CalcDue"(
    "@duedate" datetime,
    "@latefee" decimal,
    "@limit" decimal
)
RETURNS decimal
LANGUAGE SQL
NOT DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
COMMENT ''
begin

DECLARE @days int
DECLARE @TotalLateFee decimal
SET @days = DateDiff(DAY,@duedate,DATEADD(MINUTE,330,GETUTCDATE()))
if @days < 0 set @days = 0
SET @TotalLateFee = @days * @latefee

  if @TotalLateFee > @limit
    return @limit
    else return @TotalLateFee
  return isnull(@TotalLateFee,0)
end

谢谢!!

【问题讨论】:

  • DateDiff(DAY,@duedate,DATEADD(MINUTE,330,GETUTCDATE())) 到底是做什么的?
  • DateDiff() 查找日期差异
  • @duedate - (date.now +5 小时) 是这样的
  • days 是一个整数。如果duedate 和 now + 5 hours 之间的差是4 days 23 hours and 20 minutes 怎么办?那应该只有4天吗?还是舍入到 5 天?
  • @duedate 是函数中的参数

标签: database postgresql function


【解决方案1】:

完全不清楚在计算中应该如何处理分数“天”。但是 Postgres 中的一个幼稚实现可能如下所示:

CREATE FUNCTION calc_due(p_duedate timestamp, p_late_fee decimal, p_limit decimal)
  RETURNS decimal
as
$$
declare
  l_days int;
  l_total_late_fee decimal;  
begin
  l_days := extract(day from p_duedate - (current_timestamp + interval '5 hours'));
  if l_days < 0 then 
     l_days := 0;
  end if;
  l_total_late_fee := l_days * p_late_feed;
  return least(p_limit, l_total_late_fee);
end;
$$
immutable
language plpgsql;

或者更短一点的作为 SQL 函数:

CREATE FUNCTION calc_due(p_duedate timestamp, p_late_fee decimal, p_limit decimal)
  RETURNS decimal
as
$$
  select least(p_limit, greatest(0, extract(day from p_duedate - current_timestamp + interval '5 hours')) * p_late_fee);
$$
immutable
language sql;

【讨论】:

  • 我都试过了,但我得到了关于“$$”的错误。
  • 错误:“$$ declare l_days int”处或附近未终止的美元引号字符串
猜你喜欢
  • 2019-09-16
  • 1970-01-01
  • 2013-02-08
  • 2021-04-23
  • 2017-09-07
  • 2018-11-26
  • 1970-01-01
  • 2011-07-02
  • 1970-01-01
相关资源
最近更新 更多