我正在尝试使用PL / PgSQL编写dateadd()
函数。我希望能够添加从秒到几年到日期/时间戳的任何内容。拼凑了一个函数(来自网上获得的片段等),并提出了这个“实现”:
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
答案 0 :(得分:9)
你会踢自己:错误行(和接下来几行)之间的差异是你不小心在错误的地方添加了一个下划线:
你有:
HOUR_CONST_Char(15):='hour';
应该是:
HOUR_CONST Char(15):='hour';
修改强> 的
更新的问题遭遇Postgres稍微挑剔的类型系统:您的getdate()
函数正在返回timestamp with time zone
,但您的dateadd
接受timestamp
(即timestamp without time zone
})。使用Postgres简写为value::type
的演员,这应该有效(SQLFiddle demo, using now()
in place of getdate()
)
select dateadd('hour', 1, getdate()::timestamp);
但是,您还有其他一些奇怪的类型选择:
Char(15)
,但长度不是15个字符,所以用空格填充;您应该使用VarChar(15)
,或者甚至只使用text
(与MS SQL不同,在Postgres中,所有字符串都是动态存储在页外的,而VarChar
基本上只是{{1}最大长度约束)。text
,而不是Date
,因此会将输入截断为日期部分,没有时间。最后,我会注意到一个基本的优化:你不需要Timestamp
你的常数,因为你已经知道它们是小写的。 :)
答案 1 :(得分:0)
这是HOUR_CONST和Char(15)之间的下划线你应该输入“HOUR_CONST Char(15)”而不是“HOUR_CONST_Char(15)”