【发布时间】:2013-11-07 15:19:37
【问题描述】:
我正在尝试使用 PL/PgSQL 编写 dateadd() 函数。我希望能够添加从秒到年到日期/时间戳的任何内容。拼凑了一个功能(从在线获得的 sn-ps 等),并提出了这个“实现”:
CREATE OR REPLACE FUNCTION dateadd(diffType VARCHAR(15), incrementValue int, inputDate timestamp) RETURNS timestamp AS $$
DECLARE
YEAR_CONST Char(15) := 'year';
MONTH_CONST Char(15) := 'month';
DAY_CONST Char(15) := 'day';
HOUR_CONST Char(15) := 'hour';
MIN_CONST Char(15) := 'min';
SEC_CONST Char(15) := 'sec';
dateTemp Date;
intervals interval;
BEGIN
IF lower($1) = lower(YEAR_CONST) THEN
select cast(cast(incrementvalue as character varying) || ' year' as interval) into intervals;
ELSEIF lower($1) = lower(MONTH_CONST) THEN
select cast(cast(incrementvalue as character varying) || ' months' as interval) into intervals;
ELSEIF lower($1) = lower(DAY_CONST) THEN
select cast(cast(incrementvalue as character varying) || ' day' as interval) into intervals;
ELSEIF lower($1) = lower(HOUR_CONST) THEN
select cast(cast(incrementvalue as character varying) || ' hour' as interval) into intervals;
ELSEIF lower($1) = lower(MIN_CONST) THEN
select cast(cast(incrementvalue as character varying) || ' minute' as interval) into intervals;
ELSEIF lower($1) = lower(SEC_CONST) THEN
select cast(cast(incrementvalue as character varying) || ' second' as interval) into intervals;
END IF;
dateTemp:= inputdate + intervals;
RETURN dateTemp;
END;
$$ IMMUTABLE LANGUAGE plpgsql;
但是,当我尝试使用该功能时,我收到以下错误:
template1=# select dateadd('hour', 1, getdate());
ERROR: function dateadd(unknown, integer, timestamp with time zone) does not exist
LINE 1: select dateadd('hour', 1, getdate());
^
HINT: No function matches the given name and argument types. You might need to add explicit type casts.
template1=#
为什么PG找不到函数?
我在 Ubuntu 12.0.4 LTS 上运行 PG 9.3
【问题讨论】:
-
顺便说一句,这里的很多问题似乎都是在“模拟”来自 MS SQL Server 的函数。鉴于两者的行为永远不会完全一样,我不禁想到你的精力最好花在学习等效的 PostgreSQL 功能上。
-
@HomunculusReticulli 使用
intervals := interval '1 year' * incrementvalue;之类的东西可能会更好。更容易理解。 -
您是打算写一个替换相关 MS 函数的插件,还是只是为了获得一个高效的函数?
-
@ErwinBrandstetter:我现在只想要一个替代品。一旦一切正常,我会担心优化。
-
请注意,这实际上永远不会作为直接替换(就在两个 DBMS 下工作相同的查询而言),因为 MS SQL 函数将裸词作为 datepart 参数,而这里它们需要被引用字符串。由于无论如何您都在更改调用代码,因此您可以将其更改为例如
some_date + interval '2 months'(或some_date + '2 months'::interval;不知何故,我更喜欢这种语法,尽管它比 Postgres 更特殊)。
标签: postgresql plpgsql