PL/PgSQL: No function matches the given name and argument types. You might need to add explicit type casts

假如想象 提交于 2019-12-08 08:32:56

问题


I am trying to write a dateadd() function using PL/PgSQL. I want to be able to add anything from seconds, right up to years to a date/timestamp. have cobbled together a function (from snippets etc obtained online), and have come up with this "implementation":

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;

However, when I try to use the function, I get the following error:

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=# 

Why is the function not being found by PG?

I am running PG 9.3 on Ubuntu 12.0.4 LTS


回答1:


You'll kick yourself: the difference between the line that's erroring (and the next few) and the one before it is that you've accidentally added an underscore in the wrong place:

You have:

HOUR_CONST_Char(15) := 'hour';

It should be:

HOUR_CONST Char(15) := 'hour';

EDIT

The updated question is suffering from Postgres's slightly fussy type system: your getdate() function is returning timestamp with time zone, but your dateadd accepts a timestamp (i.e. timestamp without time zone). Using the Postgres short-hand for cast of value::type, this should work (SQLFiddle demo, using now() in place of getdate())

select dateadd('hour', 1, getdate()::timestamp);

However, you have a few other odd type selections:

  • Your "constants" are Char(15), but aren't 15 characters long, so will be padded with spaces; you should probably use VarChar(15), or even just text (unlike MS SQL, in Postgres, all strings are stored out-of-page dynamically, and a VarChar is essentially just text with a maximum length constraint).
  • Your intermediate variable (which can probably be refactored out) is of type Date, not Timestamp, so will truncate the input to just the date part, no time.

Finally, I'll note one fundamental optimisation: you don't need to lower() your constants, because you already know they're lower case. :)




回答2:


It's the underscore between HOUR_CONST and Char(15) You should enter "HOUR_CONST Char(15)" instead of "HOUR_CONST_Char(15)"



来源:https://stackoverflow.com/questions/19839650/pl-pgsql-no-function-matches-the-given-name-and-argument-types-you-might-need

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!