【问题标题】:Exception block in PLSQL exiting the blockPLSQL中的异常块退出块
【发布时间】:2015-02-14 17:58:51
【问题描述】:

我正在使用以下代码块来更新我的前端部分。 但是当我编译这个时

DECLARE
   p_person_id                   NUMBER          := NULL;
   p_business_group_id           NUMBER;
   p_id_flex_num                 NUMBER;
------------------
   p_analysis_criteria_id        NUMBER          := NULL;
   p_person_analysis_id          NUMBER          := NULL;
   p_per_object_version_number   NUMBER          := NULL;
   v_err                         VARCHAR2 (1000) := NULL;
   p_medical_id                  VARCHAR2 (100)  := NULL;
BEGIN
   FOR i IN (SELECT *
               FROM xx_hr_upload_master_data_new
              WHERE person_id IS NOT NULL
                AND business_group_id IS NOT NULL
                AND medical_id IS NOT NULL)
   LOOP
      p_id_flex_num := 50530;
      BEGIN
         SELECT   sv.segment1, NVL (sit.object_version_number, 1),
                  sit.analysis_criteria_id, MAX (sit.person_analysis_id)
             INTO p_medical_id, p_per_object_version_number,
                  p_analysis_criteria_id, p_person_analysis_id
             FROM fnd_id_flex_structures_tl sttl,
                  fnd_id_flex_structures st,
                  per_person_analyses sit,
                  per_analysis_criteria sv
            WHERE sttl.id_flex_structure_name = 'ISPs Medical Data'
              AND sttl.LANGUAGE = USERENV ('LANG')
              AND st.id_flex_code = sttl.id_flex_code
              AND st.id_flex_num = sttl.id_flex_num
              AND st.id_flex_num = sit.id_flex_num
              AND st.id_flex_num = sv.id_flex_num
              AND sit.analysis_criteria_id = sv.analysis_criteria_id
              AND sit.person_id = i.person_id
         --and sv.SEGMENT1 = '4602001140'
         GROUP BY sv.segment1,
                  NVL (sit.object_version_number, 1),
                  sit.analysis_criteria_id;
      EXCEPTION
         WHEN OTHERS
         THEN
            p_medical_id := NULL;
            p_per_object_version_number := 1;
            p_person_analysis_id := NULL;
            p_analysis_criteria_id := NULL;
            p_person_analysis_id := NULL;
            p_per_object_version_number := NULL;
            p_person_id := NULL;
      END;
      BEGIN
------------------------------------------------
         IF (p_medical_id IS NULL AND p_analysis_criteria_id IS NULL)
         THEN
            -- create a new record in the SIT (Special Information Type)table .
            p_person_id := i.person_id;
            p_medical_id := TO_CHAR (i.medical_id);
-----------------------------
            hr_sit_api.create_sit
                  (p_validate                       => FALSE,
                   p_person_id                      => p_person_id,
                   p_business_group_id              => i.business_group_id,
                   p_id_flex_num                    => p_id_flex_num,
                   p_effective_date                 => TRUNC (SYSDATE),
                   p_date_from                      => TRUNC (SYSDATE),
                   p_segment1                       => p_medical_id,
                   p_analysis_criteria_id           => p_analysis_criteria_id,
                   p_person_analysis_id             => p_person_analysis_id,
                   p_pea_object_version_number      => p_per_object_version_number
                  );
         ELSE
            -- employee has previous Billing_Acc_Num then update that number in  the SIT table .
            hr_sit_api.update_sit
                 (p_validate                       => FALSE,
                  p_person_analysis_id             => p_person_analysis_id,
                  p_pea_object_version_number      => p_per_object_version_number,
                  p_date_from                      => TRUNC (SYSDATE),
                  p_segment1                       => p_medical_id,
                  p_analysis_criteria_id           => p_analysis_criteria_id
                 );
         END IF;
         UPDATE xx_hr_upload_master_data_new xx
            SET xx.error_msg = 'Done',
                xx.emp_data = 'Done'
          WHERE xx.business_group_id = i.business_group_id
            AND xx.employee_number = i.employee_number;
      EXCEPTION
         WHEN OTHERS
         THEN
            p_analysis_criteria_id := NULL;
            p_person_analysis_id := NULL;
            p_per_object_version_number := NULL;
            p_person_id := NULL;
            p_medical_id := NULL;
            v_err := NULL;
            v_err := SQLERRM;
            UPDATE xx_hr_upload_master_data_new xx
               SET xx.error_msg = v_err
             WHERE xx.business_group_id = i.business_group_id
               AND xx.employee_number = i.employee_number;
      END;
   END LOOP;
   COMMIT;
END;

Now when the select query is not fetching anything, the exception block is entered where all the variables are initiated to null.

我希望在此之后开始在条件 IF 内调用 create api (p_medical_id IS NULL AND p_analysis_criteria_id IS NULL) 应输入。但这并没有发生,程序在进入异常块后在此异常块后退出。

【问题讨论】:

  • 我看不出有任何理由表明该程序应该按照您报告的方式运行。我建议在各个点添加一些 DBMS_OUTPUT.PUT_LINE 调用,以弄清楚代码流实际上是什么。您也可以将第一个异常处理程序更改为 WHEN NO_DATA_FOUND 而不是 WHEN OTHERS,如果实际上您正在尝试捕获 SELECT 未找到任何内容的条件。
  • 我在异常块中添加了 DBMS_OUTPUT.PUT_LINE。仍然会出错
  • @LalitKumarB - 像你这样没有给出解释的评论是没有帮助的。请考虑对此进行扩展。谢谢。
  • @BobJarvis,我认为exception when other then null 是一种非常常见且著名的不良编码实践。也许,你是对的,我应该添加一些解释。我试图在这里总结它lalitkumarb.wordpress.com/2014/05/02/… 我希望 Oracle 根本不会允许它,但是,在 11g 之后我们确实有一个警告,唉!很少有开发人员甚至不在乎。我会建议开发人员,至少不要有任何异常块 wgile 测试阶段。让所有错误在测试阶段出现。
  • 使用调试器将帮助您追踪问题。你在使用 IDE 吗?您的帖子被标记为“PLSQL Developer”。如果这意味着 IDE 同名,则使用内置调试器。

标签: oracle api plsql plsqldeveloper


【解决方案1】:

提示可能是: 如果没有结果,第一个选择不会引发任何异常。如果没有结果,那么就不会进入 for 循环,所以唯一会发生的事情就是提交。 (for-loop 中的 select 如果得到 0 行或多于 1 行,将引发异常。原因是 'select ... into ...':当使用 'into' 时,select 必须返回精确的 1 行。 )

【讨论】:

    猜你喜欢
    • 2016-05-08
    • 1970-01-01
    • 2010-10-03
    • 1970-01-01
    • 2012-04-16
    • 1970-01-01
    • 2011-03-25
    相关资源
    最近更新 更多