将游标值调用到异常中

Calling Cursor Value into Exception

我有一个游标作为包的一部分,它比较 2 table 的计数。如果计数匹配,则执行包的其余部分。但如果失败,它应该更新日志 table 中的计数。 光标代码为

    CURSOR C_CNT IS
      SELECT
        lnd.sml_batchrun_id batch_id,
        lnd.lnd_count,
        dwh.dwh_count
      FROM
        (
         SELECT
          sml_batchrun_id,
          COUNT(*) lnd_count
         FROM
          iva_landing.lnd_sml_t
        GROUP BY
          sml_batchrun_id
        ) lnd
       LEFT JOIN (
        SELECT
         batchrun_id,
         sent_records_count dwh_count,
         dwh_sending_table
        FROM
         dwh.dwh_idh_to_iva_metadata_t
         ) dwh ON dwh.batchrun_id = lnd.sml_batchrun_id
        WHERE dwh.dwh_sending_table = 'DWH_SML_T'
        ORDER BY
      1 DESC;

比较代码为:

    FOR L_COUNT IN C_CNT LOOP        --0001,0002
      IF L_COUNT.lnd_count = L_COUNT.dwh_count THEN
       UPDATE DWH.DWH_IDH_TO_IVA_METADATA_T idh
       SET idh.IVA_RECEIVING_TABLE = 'LND_SML_T',
       idh.RECEIVED_DATE = SYSDATE,
       idh.RECEIVED_RECORDS_COUNT = L_COUNT.lnd_count,
       idh.status = 'Verified'
       WHERE L_COUNT.batch_id = idh.batchrun_id
       AND idh.dwh_sending_table = 'DWH_SML_T';
       COMMIT;
      ELSE
       RAISE  EXCPT_SML_MISSDATA;  -- Throw  error and exit process 
      END IF;
     END LOOP;

现在,在异常处理部分,我想在日志的错误列中显示计数table

    logger.log_error('IVA-MSG 200-010 - COUNT MISMATCH! - Aborting',  p_log_id=>l_job_log.log_id);
     l_job_log.end_date     := systimestamp;
     l_job_log.error_mesg   := cur_cnt.dwh_count||' '|| cur_cnt.lnd_count;
     l_job_log.status       := iva_log.iva_job_log_pck.c_str_statusfailed;
     iva_log.iva_job_log_pck.change_joblog_prc(pi_rec_joblog => l_job_log);
     RAISE;

这里,cur_cnt是定义为cur_cnt c_cnt%rowtype;的变量 和 l_job_log 作为 l_job_log iva_log.iva_job_log_t%rowtype;

其中 iva_job_log_t 是日志 table 名称。 但在触发包后,计数在错误列中不可见。此外,如果我将 iva_job_log_t 的内容放在单引号中,那么它会显示在日志中 table.

请建议如何显示光标的计数。

谢谢

如果你还在做

FOR L_COUNT IN C_CNT LOOP

那么您的 cur_cnt 变量永远不会被填充;它将是它被声明为的空记录,因此引用它的任何字段将始终为您提供 null。

您可以参考错误日志中的l_count值:

l_job_log.error_mesg := l_count.dwh_count ||' '|| l_count.lnd_count;

...就像你在循环中的其他地方所做的那样。

如果异常处理程序当前在进程的后面,所以 l_count 超出范围(如 re-raise 可能暗示的那样),那么您可以移动它,使其在 else 内分开:

FOR L_COUNT IN C_CNT LOOP        --0001,0002
  IF L_COUNT.lnd_count = L_COUNT.dwh_count THEN
   UPDATE DWH.DWH_IDH_TO_IVA_METADATA_T idh
   SET idh.IVA_RECEIVING_TABLE = 'LND_SML_T',
   idh.RECEIVED_DATE = SYSDATE,
   idh.RECEIVED_RECORDS_COUNT = L_COUNT.lnd_count,
   idh.status = 'Verified'
   WHERE L_COUNT.batch_id = idh.batchrun_id
   AND idh.dwh_sending_table = 'DWH_SML_T';
   COMMIT;
  ELSE
   logger.log_error('IVA-MSG 200-010 - COUNT MISMATCH! - Aborting',  p_log_id=>l_job_log.log_id);
   l_job_log.end_date     := systimestamp;
   l_job_log.error_mesg   := l_count.dwh_count||' '|| l_count.lnd_count;
   l_job_log.status       := iva_log.iva_job_log_pck.c_str_statusfailed;
   iva_log.iva_job_log_pck.change_joblog_prc(pi_rec_joblog => l_job_log);
   RAISE  EXCPT_SML_MISSDATA;  -- Throw  error and exit process 
  END IF;
 END LOOP;

否则,您将不得不更改游标循环处理以提取到变量中,而是在循环中引用它,并在以后依靠它具有正确的值:

OPEN C_CNT
LOOP
  FETCH C_CNT INTO CUR_CNT;
  EXIT WHEN C_CNT%NOTFOUND;

  IF CUR_CNT.lnd_count = CUR_CNT.dwh_count THEN
   UPDATE DWH.DWH_IDH_TO_IVA_METADATA_T idh
   SET idh.IVA_RECEIVING_TABLE = 'LND_SML_T',
   idh.RECEIVED_DATE = SYSDATE,
   idh.RECEIVED_RECORDS_COUNT = CUR_CNT.lnd_count,
   idh.status = 'Verified'
   WHERE CUR_CNT.batch_id = idh.batchrun_id
   AND idh.dwh_sending_table = 'DWH_SML_T';
   COMMIT;
  ELSE
   RAISE  EXCPT_SML_MISSDATA;  -- Throw  error and exit process 
  END IF;
 END LOOP;

您以后的异常处理程序应该可以按原样工作。