【问题标题】:How to convert this T-SQL code to PostgreSQL / plpgsql如何将此 T-SQL 代码转换为 PostgreSQL / plpgsql
【发布时间】:2010-07-29 10:48:18
【问题描述】:

我需要将以下 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

【问题讨论】:

  • 这似乎是一个函数。函数的名称是什么,函数的@Date、@Interval 和@Type 参数是什么?查看函数声明会很有帮助。

标签: sql tsql postgresql datetime plpgsql


【解决方案1】:

知道了:

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;

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

【讨论】:

  • 你只需要那些双引号,因为你做了整个@Uppercase的事情。放下案例以降低并放下引号 - 然后它更正常的 plpgsql。
【解决方案2】:

我将你的函数翻译成现代的“本机”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。它是一个标识符,而不是一个字符串;目前可以容忍,但可能会导致问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多