问题
I'm looking for a way to create an icase() function which works with any second and third parameter compatible data types.
I tried in Postgres 9.4:
CREATE OR REPLACE FUNCTION public.icase(
cond1 boolean,
res1 anyelement,
conddefault anyelement)
RETURNS anyelement AS
' SELECT CASE WHEN $1 THEN $2 ELSE $3 END; '
LANGUAGE sql IMMUTABLE;
But:
select icase( true, 1.0, 0 )
causes error:
ERROR: function icase(boolean, numeric, integer) does not exist LINE 9: select icase( true, 1.0, 0 ) ^ HINT: No function matches the given name and argument types. You might need to add explicit type casts.
How to fix this in 9.1+ so that second and third arguments can be either int or numeric?
This method may be called if both second and third parameters are text, char(n), date, numeric or int types.
回答1:
The polymorphic types are strict in this moment - in other cases, PostgreSQL try to cast constants to most common type, but this step is missing for polymorphic types - so in this case, when you have described issue, you have to cast explicitly or you should not to use polymorphic types. Plan B is over function overloading.
CREATE OR REPLACE FUNCTION public.icase1(cond1 boolean,
res1 integer, conddefault integer)
RETURNS integer AS $$
SELECT CASE WHEN $1 THEN $2 ELSE $3 END;
$$ LANGUAGE sql;
CREATE OR REPLACE FUNCTION public.icase1(cond1 boolean,
res1 numeric, conddefault numeric)
RETURNS numeric AS $$
SELECT CASE WHEN $1 THEN $2 ELSE $3 END;
$$ LANGUAGE sql;
Then your code will work as expected:
postgres=> select icase1(true, 1.0, 0);
icase1
--------
1.0
(1 row)
postgres=> select icase1(true, 1.0, 1.0);
icase1
--------
1.0
(1 row)
postgres=> select icase1(true, 1, 0);
icase1
--------
1
(1 row)
来源:https://stackoverflow.com/questions/30330555/how-to-use-mixed-int-and-numeric-arguments-in-a-postgres-9-1-function