【问题标题】:query inside the exception and begin block in exception在异常中查询并在异常中开始块
【发布时间】:2021-03-11 16:54:11
【问题描述】:

您好,我想问一下最佳做法是什么。

第一个示例尝试通过异常检索数据

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;

第二个示例尝试使用案例检索数据并使用 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;

【问题讨论】:

    标签: sql oracle plsql oracle-sqldeveloper plsqldeveloper


    【解决方案1】:

    亲身经历...

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

    将那些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 个示例中,您在内部块中声明变量,但在外部块中调用它们 - 这是要避免的。

    【讨论】:

    • 抱歉回复晚了,我更改了代码并按照您所说的使用函数进行操作,我认为更具可读性。感谢您分享您的知识!
    【解决方案2】:

    最佳做法是始终保持代码简洁易读。 为了保持你的代码干净和可读,让它结构良好。 为了使其结构良好,您必须将代码拆分为单元,每个单元只做一件事 - 有一个职责。

    阅读更多关于 SOLID 原则、DRY 原则的信息。

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

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

    【讨论】:

    • 非常感谢您的回答!我会阅读您发送的文件。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-08
    • 2019-06-14
    • 2013-04-18
    • 1970-01-01
    • 2020-01-16
    • 1970-01-01
    相关资源
    最近更新 更多