问题
Is there an equivalent (or workaround) for the RAISE EXCEPTION statement for the function written below in LANGUAGE sql
?
CREATE OR REPLACE FUNCTION fn_interpolation (p_yearinteger integer,
p_admin_id integer, p_crop_id integer, p_cropparameter integer)
RETURNS TABLE (value double precision, remark text)
AS $$
WITH
yearvalues AS (SELECT yearinteger, value FROM cropvalues WHERE crops_id =
p_crop_id AND admin_id = p_admin_id AND parameter_id = p_cropparameter),
I need the function to abort and to RETURN an error message if the arguments entered into the function do not exist. e.g. IF parameter_id != p_cropparameter THEN RAISE EXCEPTION ‘invalid cropparameter’ END IF
回答1:
Just define a trivial wrapper function.
CREATE OR REPLACE FUNCTION raise_exception(text) RETURNS text AS $$
BEGIN
RAISE EXCEPTION '%',$1;
END;
$$ LANGUAGE plpgsql VOLATILE;
then use CASE
:
SELECT CASE
WHEN parameter_id != p_cropparameter
THEN raise_exception("blah")
ELSE parameter_id
END;
This only works if the CASE
otherwise returns text
though, e.g. if parameter_id
is integer you get:
regress=> SELECT CASE WHEN 1 = 2 THEN raise_exception('blah') ELSE 1 END;
ERROR: CASE types integer and text cannot be matched
LINE 1: SELECT CASE WHEN 1 = 2 THEN raise_exception('blah') ELSE 1 E...
You can work around this with a hack using polymorphic functions. Define:
CREATE OR REPLACE FUNCTION raise_exception(anyelement, text) RETURNS anyelement AS $$
BEGIN
RAISE EXCEPTION '%',$2;
RETURN $1;
END;
$$ LANGUAGE plpgsql VOLATILE;
then pass a fake value of the case type to it so PostgreSQL type-matches it correctly, e.g.
SELECT CASE WHEN 1 = 1 THEN raise_exception(0, 'blah') ELSE 1 END;
or
SELECT CASE WHEN 1 = 1 THEN raise_exception(NULL::integer, 'blah') ELSE 1 END;
All seem too hard? That's because really, this sort of thing is usually just better done in PL/PgSQL.
来源:https://stackoverflow.com/questions/24882630/equivalent-or-alternative-method-for-raise-exception-statement-for-function-in-l