перенесите функцию sqlserver в postgres

#database #postgresql #function

Вопрос:

У меня есть функция в SQL server, которая вычисляет причитающуюся сумму. Я перенес свою базу данных в Postgres, но я не могу использовать эту функцию в Postgres, потому что обе базы данных имеют разную схему и синтаксис. Я новичок в Postgres и не знаю, как перенести эту функцию в Postgres с SQL-сервера. вот функция, пожалуйста, помогите мне преобразовать ее.

 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
 

Спасибо!!

Комментарии:

1. Что именно DateDiff(DAY,@duedate,DATEADD(MINUTE,330,GETUTCDATE())) он делает?

2. DateDiff() найдите разницу в дне

3. @duedate — (дата.сейчас 5 часов) что-то вроде этого

4. days является целым числом. Что делать, если разница между duedate сегодняшним днем и 5 часами составляет 4 days 23 hours and 20 minutes ? Должно ли это быть всего за 4 дня? Или округлить его до 5 дней?

5. @duedate является параметром в функции

Ответ №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;
 

Комментарии:

1. Я попробовал их оба, но получил ошибку о»$$».

2. ОШИБКА: строка в долларовых кавычках без изменений в «$$ declare l_days int»или около» $ $ declare l_days int»