如何获取 PL/SQL 关联数组 DS 的 NULL 条件检查

Posted

技术标签:

【中文标题】如何获取 PL/SQL 关联数组 DS 的 NULL 条件检查【英文标题】:How to get NULL condition checks for PL/SQL associative array DS 【发布时间】:2013-10-04 15:07:49 【问题描述】:

我有以下代码 sn-p,我想知道如何检查关联数组中是否存在条目

set serveroutput on;
DECLARE
    TYPE per_form_metric IS record
      (
              output_achieved_itd NUMBER,
              output_achieved_ptd NUMBER
      );
      TYPE per_form_metrics_tbl IS TABLE OF per_form_metric INDEX BY VARCHAR2(10) ;
      TYPE interval_number_tbl IS TABLE OF per_form_metrics_tbl INDEX BY VARCHAR2(10) ;
      TYPE ms_output_tbl IS TABLE OF interval_number_tbl INDEX BY VARCHAR2(100) ;
      g_ms_output_tbl ms_output_tbl ;

      l_per_f_rec        per_form_metric;
      l_per_f_tbl        per_form_metrics_tbl;
      l_per_int_tbl     interval_number_tbl;
      l_ms_out_tbl    ms_output_tbl;

 BEGIN
    l_per_f_rec.output_achieved_itd := 1000;
    l_per_f_rec.output_achieved_ptd := 1000;

    l_per_f_tbl('Period 1') := l_per_f_rec;

    l_per_int_tbl('Interval 1') := l_per_f_tbl;

    l_ms_out_tbl('1') := l_per_int_tbl;

    -- Now get me the output_achieved_itd for 1 , Interval 1, Period 1

    dbms_output.put_line(l_ms_out_tbl('1')('Interval 1')('Period 1').output_achieved_itd);

    dbms_output.put_line(l_ms_out_tbl('2')('Interval 1')('Period 1').output_achieved_itd);


END;

这段代码的输出如下

Error report:
ORA-01403: no data found
ORA-06512: at line 31
01403. 00000 -  "no data found"
*Cause:    
*Action:
1000

我如何检查是否

l_ms_out_tbl('2')('Interval 1')('Period 1').output_achieved_itd 

存在吗?

我想说一些类似的话

IF (l_ms_out_tbl('2')('Interval 1')('Period 1').output_achieved_itd IS NOT NULL) THEN
    do something awesome
  ELSE 
    continue wallowing
  END IF;

【问题讨论】:

【参考方案1】:

评估存在性,而不是评估是否存在:

IF (l_ms_out_tbl.EXISTS('2'))
THEN
   IF (l_ms_out_tbl('2').EXISTS('Interval 1'))
   THEN
      IF (l_ms_out_tbl('2')('Interval 1').EXISTS('Period 1'))
      THEN
         null; --do something awesome
      END IF;
   END IF;
ELSE 
    null; --continue wallowing
END IF;

或抓住 NO_DATA_FOUND:

begin
   dbms_output.put_line(l_ms_out_tbl('2')('Interval 1')('Period 1').output_achieved_itd)
   -- did something awesome
exception
   when NO_DATA_FOUND then
      null;
      -- continue wallowing
end;

【讨论】:

【参考方案2】:

使用exists收集方法。例如:

declare
  type foo_t is table of varchar2(20) index by varchar2(20);
  v_foos foo_t;
begin
  v_foos('FOO') := 'this is foo';

  if v_foos.exists('FOO') then
    dbms_output.put_line('exists');
  else
    dbms_output.put_line('not exists');
  end if;
end;
/

如何将其应用于嵌套关联数组留给 OP :)

另见:

PL/SQL - Working with a string! Why is this check for null associative array in PL/SQL failing?

【讨论】:

以上是关于如何获取 PL/SQL 关联数组 DS 的 NULL 条件检查的主要内容,如果未能解决你的问题,请参考以下文章

PL/SQL 关联数组验证索引是不是存在

在 PL/SQL 中重置关联数组?

更新另一列时,使用列名作为 PL/SQL 关联数组的键

PL/SQL集合(table)嵌套表操作实例讲解实例

PL/SQL数组

SQL记录-PLSQL集合