在异常中查询并在异常中开始块

query inside the exception and begin block in exception

你好我想问一下最好的做法是什么

第一个示例尝试通过异常检索我的数据我在我的主应用程序中使用此代码并且工作正常但我不知道在异常块中编码是否是好的做法

BEGIN   
    DECLARE
        v_status varchar2(100);
        v_flag varchcar2(100);
    BEGIN 
        SELECT STATUS INTO v_status FROM TABLE1 WHERE condition1;
    EXCEPTION 
        when no_data_found then 
            select FLAG INTO v_flag FROM TABLE2   WHERE condition1; -- THERE WILL BE 100% RECORD 
            
            IF v_flag='N' THEN 
                V_STATUS:='N'
            ELSIF v_flag:='O'
                V_STATUS:='O'
            ELSE
                BEGIN 
                    SELECT STATUS INTO V_STATUS FROM TABLE3 WHERE condition1,condition2;
                EXCEPTION 
                    V_STATUS:='F';
                END;
            END IF;         
    END;

    IF V_STATUS='O' THEN 
        --DO SOMETHING HERE 
    ELSIF V_STATUS='N' THEN 
        --DO SOMETHING HERE 
    ELSE 
        --DO SOMETHING HERE
    END IF;
END;

第二个示例尝试使用 CASES 和 SELECT 使用 COUNT 检索数据。

BEGIN   
    DECLARE 
        V_CNTR NUMBER;
        V_STATUS VARCHAR2(100);
    BEGIN 
        SELECT COUNT(1) INTO V_CNTR FROM TABLE1 WHERE condition1;
        CASE 
            WHEN COUNT=1 THEN 
                SELECT STATUS INTO V_STATUS FROM TABLE1 WHERE condition1; 
            ELSE 
                select FLAG INTO v_flag FROM TABLE2   WHERE condition1; -- THERE WILL BE 100% RECORD 
                
                IF v_flag='N' THEN 
                    V_STATUS:='N'
                ELSIF v_flag:='O'
                    V_STATUS:='O'
                ELSE 
                        SELECT COUNT(1) INTO V_CNTR FROM TABLE3 WHERE condition1,condition2;
                    CASE 
                        WHEN count=1 THEN 
                            SELECT STATUS INTO V_STATUS FROM TABLE3 WHERE condition1,condition2;
                        ELSE 
                            V_STATUS:='F';
                    END CASE; 
                END IF;         
        END CASE;
    END;

    IF V_STATUS='O' THEN 
        --DO SOMETHING HERE 
    ELSIF V_STATUS='N' THEN 
        --DO SOMETHING HERE 
    ELSE 
        --DO SOMETHING HERE
    END IF;
END;

根据个人经验...

那些嵌套块工作正常,在异常块中使用代码可能很有用,但它很快就会变得非常不可读,如您在示例中所示。如果您的初始代码看起来像这样,那么想象一下几个开发周期之后它会是什么样子。

将那些 BEGIN SELECT INTO EXCEPTION WHEN NO_DATA_FOUND THEN... END: 块移动到函数中会更干净。使代码更加结构化、可读性更强并且更易于调试和维护:

DECLARE
  v_status varchar2(100);
  v_flag varchcar2(100);
  FUNCTION status (argument_i VARCHAR2) RETURN VARCHAR2
  IS
    l_status VARCHAR2(100);
  BEGIN
    SELECT STATUS INTO v_status FROM TABLE1 WHERE condition = argument_i;
  EXCEPTION WHEN NO_DATA_FOUND THEN
    RETURN NULL; -- or -1 or NOTFOUND - whatever you prefer
  END;
BEGIN
  v_status := status(argument_i => condition);
  IF v_status IS NULL THEN
    ...
  ELSE
    ...
  END IF;
END; 

这是一个内联函数 - 在包内您可以使用独立函数,如果从不在包外调用则为私有函数。 请注意,在您的 2 个示例中,您在内部块中声明了变量,但在外部块中调用了它们——这是要避免的事情。

最佳做法是始终保持代码整洁和可读。 为了保持代码的整洁和可读性,请使其结构合理。 为了使其结构良好,您必须将代码拆分为单元,每个单元只做一件事 - 承担一项责任。

阅读更多关于 SOLID 原则和 DRY 原则的信息以获得想法。

对您问题的简短回答: 在异常块中编码不是我要遵循的最佳实践。

查看 this presentation on clean PL/SQL coding 以获得更全面的概述。