【问题标题】:Postgres ExceptionsPostgres 异常
【发布时间】:2020-10-28 21:24:27
【问题描述】:

我需要将一些 Oracle PL/SQL 代码移植到 Postgres。这是我第一次使用 Postgres。

在 Oracle 中,关于异常,我可以这样:

IF v_customer_id 为 NULL 或 v_email 为 NULL THEN 提高无效参数; 万一;

在 Postgres 中是如何做到的?基本上验证输入,如果有任何验证失败,调用自定义处理程序来执行任何操作。根据我的阅读,Postgres 不支持自定义命名异常。

感谢您的宝贵时间。

【问题讨论】:

    标签: postgresql exception


    【解决方案1】:

    您可以将RAISE 与自定义消息和特定的 sqlstate 常量一起使用:

    --Anonymous block for testing purposes
    DO $$
    BEGIN
        RAISE invalid_parameter_value USING MESSAGE = 'Invalid customer or email';
    END $$;
    

    或者您可以简单地引发一个通用异常:

    DO $$
    BEGIN
        RAISE EXCEPTION 'A generic exception (P0001)';
    END $$;
    

    你也可以处理异常:

    DO $$
    BEGIN
        --This will raise a division by zero
        PERFORM 0 / 0;
    
    --You can catch a exception with a EXCEPTION block
    EXCEPTION
        WHEN division_by_zero THEN
            RAISE INFO 'Division by zero catched';  
        WHEN raise_exception THEN
            RAISE INFO 'Another error catched...';          
    END $$; 
    

    并获取有关异常的更多详细信息:

    DO $$
    DECLARE
        error_msg text;
    BEGIN
        --This will raise a division by zero
        PERFORM 0 / 0;
    
    --You can get more about error with GET STACKED DIAGNOSTICS
    EXCEPTION
        --Tip: OTHERS keyword will catch any exception
        WHEN OTHERS THEN
          GET STACKED DIAGNOSTICS error_msg = MESSAGE_TEXT;
            RAISE EXCEPTION 'My custom exception: %', error_msg;
    END $$; 
    

    我建议您查看 sqlstatescontrol structures 以了解有关 PostgreSQL 中错误处理的更多信息。

    【讨论】:

    • 如果在某个特定的块中我可能不想退出该过程,它是如何工作的。我想捕捉异常并做点什么。也许在另一个块中,我希望异常基本上退出该过程。在 Oracle 中,您可以编写异常代码,将其放在最后一个异常处理程序中,如果该错误发生并且未在现有块中捕获,则该过程将下降到定义的位置。
    【解决方案2】:
    do $$
    declare
        v int := 1;
    begin
        begin
            if v < 2 then -- Validation here
                raise sqlstate 'A0001'; -- custom SQL state, any five upper case letters and/or digits
            end if;
        exception -- Catch exception in the nested BEGIN ... END block
            when sqlstate 'A0001' then
                raise notice 'Here is my exception handler';
                v := 2;
        end;
        raise notice 'Continue here with value %', v; -- Reports that the v = 2
    end $$;
    

    【讨论】:

      【解决方案3】:

      您可以添加一个嵌套的begin...end 块来代替RAISE EXCEPTION 部分,并在其中引发异常并在嵌套块内的其他异常块中使用@ 捕获它,而不是在主异常块中捕获它987654323@ 关键字。希望对您有所帮助。

      do
      $$
      begin
       raise notice 'line 1';
       begin
        raise exception 'raising exception';
       exception
        when others then
         raise notice 'captured in nested block';
       end;
        return;
        raise notice 'check if it continues';
      exception
       when others then
        raise notice 'main block others';
      end;
      $$
      language plpgsql;
      

      【讨论】:

        猜你喜欢
        • 2018-08-15
        • 1970-01-01
        • 2016-03-07
        • 2020-09-27
        • 2013-11-01
        • 2016-04-26
        • 1970-01-01
        • 1970-01-01
        • 2015-03-08
        相关资源
        最近更新 更多