如何将此T-SQL代码转换为PostgreSQL / plpgsql

时间:2010-07-29 10:48:18

标签: sql tsql postgresql datetime plpgsql

我需要将以下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 个答案:

答案 0 :(得分:3)

知道了:

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;

也许其他人都需要这样的东西。

答案 1 :(得分:3)

我将你的功能翻译成现代的“原生”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

  • 使用小写parameter names代替引用的混合大小写T-SQL样式参数语法。

  • 删除无意义的_interval转换为十进制(不会改变结果)。

  • 删除未使用的_mystamp

  • 删除未使用的DECLARE

  • 使用更合适的CASE代替IF

  • 永远不要引用语言名称plpgsql。它是一个标识符,而不是字符串;现在容忍,但可能会导致问题。