I need to convert the following tsql function code into a plpgsql function and I have absolutely no idea how:
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
Here is the fullquote:
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(DA开发者_StackOverflow社区TEDIFF(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
Got it:
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;
Maybe anyone else needs something like this.
I translated your function to modern "native" 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;
Major points
datetime
maps totimestamp
, nottimestamp with timezone
Use lower case parameter names instead of quoted mixed case T-SQL style parameter syntax.
Remove pointless cast of _interval to decimal (doesn't change result).
Remove unused
_mystamp
.Remove therefore unused
DECLARE
.Use better suited
CASE
instead ofIF
.Never quote the language name
plpgsql
. It's an identifier, not a string; tolerated for now, but may lead to problems.
精彩评论