Как преобразовать этот код T-SQL в PostgreSQL / plpgsql - PullRequest
0 голосов
/ 29 июля 2010

Мне нужно преобразовать следующий код функции tsql в функцию plpgsql, и я понятия не имею, как:

BEGIN
    DECLARE @StartDate DATETIME
    DECLARE @ResultDate DATETIME

    SET @StartDate = CONVERT(DATETIME, 0)

    SET @ResultDate = 
    CASE @Type
        WHEN 0 THEN DATEADD(mi, FLOOR(DATEDIFF(mi, @StartDate, @Date) / CAST(@Interval AS FLOAT)) * @Interval, @StartDate)
        WHEN 1 THEN DATEADD(mi, CEILING(DATEDIFF(mi, @StartDate, @Date) / CAST(@Interval AS FLOAT)) * @Interval, @StartDate)
        ELSE @Date
END

RETURN @ResultDate

Вот полная кавычка:

set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
GO

ALTER FUNCTION [dbo].[GetIntervalDate] 

(
    @Date DATETIME,
    @Type INT,
    @Interval INT
)  
RETURNS DATETIME

AS

BEGIN

DECLARE @StartDate DATETIME

DECLARE @ResultDate DATETIME

    SET @StartDate = CONVERT(DATETIME, 0)

    SET @ResultDate = 
    CASE @Type
        WHEN 0 THEN DATEADD(mi, FLOOR(DATEDIFF(mi, @StartDate, @Date) / CAST(@Interval AS FLOAT)) * @Interval, @StartDate)
        WHEN 1 THEN DATEADD(mi, CEILING(DATEDIFF(mi, @StartDate, @Date) / CAST(@Interval AS FLOAT)) * @Interval, @StartDate)
        ELSE @Date
    END

    RETURN @ResultDate
END

Ответы [ 2 ]

3 голосов
/ 22 октября 2011

Я перевел вашу функцию на современный "нативный" plpgsql:

CREATE OR REPLACE FUNCTION get_interval_date(_ts timestamp
                                            ,_type int
                                            ,_interval int)
  RETURNS timestamp AS
$func$
BEGIN
   CASE _type 
   WHEN 0 THEN
      RETURN timestamp 'epoch'
           + floor((extract(EPOCH FROM _ts)) / _interval)
           * _interval * interval '1s';
   WHEN 1 THEN
      RETURN timestamp 'epoch'
           + ceil((extract(EPOCH FROM _ts)) / _interval)
           * _interval * interval '1s';
   ELSE
      RETURN _ts;
   END CASE;
END
$func$ LANGUAGE plpgsql IMMUTABLE;

Основные точки

  • datetime отображается на timestamp, а не timestamp with timezone

  • Использовать строчные имена параметров вместо синтаксиса в кавычках в синтаксисе стиля T-SQL.

  • Удалить бессмысленное приведение _interval к ​​десятичному числу (результат не меняется).

  • Удалить неиспользуемое _mystamp.

  • Удалите поэтому неиспользованные DECLARE.

  • Используйте более подходящие CASE вместо IF.

  • Никогда не указывайте название языка plpgsql.Это идентификатор, а не строка;пока терпимо, но может привести к проблемам.

3 голосов
/ 29 июля 2010

Понял:

CREATE FUNCTION get_interval_date("@Date" timestamp, "@Type" int, "@Interval" int)
    RETURNS timestamp with time zone AS
$BODY$
DECLARE
    _mystamp timestamp;
    _round_secs decimal;
BEGIN
    _round_secs := "@Interval"::decimal;

    IF "@Type" = 0 THEN
        RETURN timestamptz 'epoch'
             + FLOOR((EXTRACT(EPOCH FROM "@Date"))::int / _round_secs) * _round_secs * INTERVAL '1 second';
    ELSIF "@Type" = 1 THEN  
        RETURN timestamptz 'epoch'
             + CEIL((EXTRACT(EPOCH FROM "@Date"))::int / _round_secs) * _round_secs * INTERVAL '1 second';
    ELSE
        RETURN "@Date";
    END IF;
END;
$BODY$ LANGUAGE 'plpgsql' IMMUTABLE;

Может, кому-то еще нужно что-то подобное.

...