如何在 PL/pgSQL EXCEPTION 块中重新引发异常?

jpm*_*c26 6 postgresql exception plpgsql

考虑函数内的以下(不完整的)PL/pgSQL 块:

CREATE OR REPLACE FUNCTION my_calc(myvar1 NUMERIC, myvar2 NUMERIC)
    RETURNS NUMERIC
    RETURNS NULL ON NULL INPUT
    IMMUTABLE
    LANGUAGE plpgsql
    AS $$
    BEGIN
        RETURN some_third_party_function(myvar1, myvar2);
    EXCEPTION WHEN internal_error THEN
        IF SQLERRM LIKE 'KnownErrorPrefix:%' THEN
            RETURN 0;
        ELSE
            -- Reraise the original exception here
            RAISE EXCEPTION '%', SQLERRM;
        END IF;
    END
    $$
Run Code Online (Sandbox Code Playgroud)

当发生意外错误时,此代码将引发具有相同消息的新异常。但是,它不会保留原始类型或上下文。

如何重新引发或重新抛出未修改的原始异常?

jpm*_*c26 11

您可以RAISE不带任何参数使用。这记录在错误和消息页面上:

的最后一个变体RAISE根本没有参数。这种形式只能在BEGIN块的EXCEPTION子句中使用;它会导致重新抛出当前正在处理的错误。

CREATE OR REPLACE FUNCTION my_calc(myvar1 NUMERIC, myvar2 NUMERIC)
    RETURNS NUMERIC
    RETURNS NULL ON NULL INPUT
    IMMUTABLE
    LANGUAGE plpgsql
    AS $$
    BEGIN
        RETURN some_third_party_function(myvar1, myvar2);
    EXCEPTION WHEN internal_error THEN
        IF SQLERRM LIKE 'KnownErrorPrefix:%' THEN
            RETURN 0;
        ELSE
            -- Reraise the original exception here
            RAISE;
        END IF;
    END
    $$
Run Code Online (Sandbox Code Playgroud)