问题
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(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
回答1:
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.
回答2:
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 to timestamp, not
timestamp with timezoneUse 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 of
IF.Never quote the language name
plpgsql. It's an identifier, not a string; tolerated for now, but may lead to problems.
来源:https://stackoverflow.com/questions/3361660/how-to-convert-this-t-sql-code-to-postgresql-plpgsql