问题
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