Oracle PL/SQL气泡排序-ORA-01403:在第12行找不到ORA-06512:数据

Oracle PL/SQL气泡排序-ORA-01403:在第12行找不到ORA-06512:数据,oracle,plsql,Oracle,Plsql,代码如下: declare p_arr dbms_sql.Number_Table; i pls_integer; procedure do_sort(p_arr in out dbms_sql.Number_Table, p_asc in boolean default null, p_nulls_last in boolean default null) is x pls_integer; p_temp number; begin fo

代码如下:

declare  
  p_arr dbms_sql.Number_Table;  
  i pls_integer;  
  procedure do_sort(p_arr in out dbms_sql.Number_Table, p_asc in boolean default null, p_nulls_last in boolean default null) is  
  x pls_integer; 
  p_temp number; 
  begin    
  for i in 1..p_arr.COUNT-1  
    loop  
      for x in 2..p_arr.COUNT  
      loop  
        if p_arr(x) < p_arr(x-1)  
        then  
          p_temp := p_arr(x-1);  
          p_arr(x-1) := p_arr(x);  
          p_arr(x) := p_temp;  
        end if; 
      end loop; 
    end loop; 
    return;  
  end;  
begin  
  p_arr(-1) := 0;  
  p_arr(0) := -2;  
  p_arr(1) := 10.1;  
  p_arr(2) := null;   
  p_arr(3) := 10.1;  
  p_arr(4) := -1;  
  do_sort(p_arr);  
  i := p_arr.first;  
  while i is not null loop  
    dbms_output.put_line('arr('||i||') = '||nvl(to_char(p_arr(i)), 'null')||';');  
    i := p_arr.next(i);  
  end loop;  
end;
声明
p_arr dbms_sql.Number_表;
我喜欢整数;
过程do_sort(p_arr in out dbms_sql.Number_Table,p_asc in boolean default null,p_nulls_last in boolean default null)为
x pls_整数;
p_温度编号;
开始
对于i in 1..p_arr.COUNT-1
环
对于2..p_arr.COUNT中的x
环
如果p_arr(x)
它在第12行给了我一个错误——“找不到数据”。 第29行的“do_sort”程序也分别失败

似乎是嵌套循环的问题,我现在还不能解决。 当只有包含一些代码的“第一级”循环时,例如为集合分配新值,它的性能很好

程序体外部的排序块也可以工作


提前感谢。

您正在用特定索引填充数字表:

  p_arr(-1) := 0;  
  p_arr(0) := -2;  
  p_arr(1) := 10.1;  
  p_arr(2) := null;   
  p_arr(3) := 10.1;  
  p_arr(4) := -1;  
但是当您循环时,您使用的是从1到元素计数(即6)的索引值。没有索引为5或6的元素,当您尝试引用
p\u arr(5)
时,没有此类元素-因此出现错误。你错过了那些索引为-1和0的

如果对初始值重新编制索引,则该方法有效:

  p_arr(1) := 0;  
  p_arr(2) := -2;  
  p_arr(3) := 10.1;  
  p_arr(4) := null;   
  p_arr(5) := 10.1;  
  p_arr(6) := -1;  
然后获取输出:

arr(1) = -2;
arr(2) = 0;
arr(3) = 10.1;
arr(4) = null;
arr(5) = -1;
arr(6) = 10.1;

PL/SQL procedure successfully completed.
注意你的空值会发生什么。。。您无法将null与任何其他内容进行比较,因此当在比较的两侧计算null元素时,
p_arr(x)
是未定义的(但不是真的)。所以,它不动了。您需要决定null的最终位置,以确定如何修改代码来实现这一点

如果您有一个特定的原因要在-1而不是1开始索引,那么您仍然可以这样做,并将循环中的引用更改为
p_arr(x+2)
等,但这将更容易混淆和出错。或者您可以更改循环范围以处理该问题:

  for i in -1..p_arr.COUNT - 1 -- 2 less than previously, on each end of range
    loop  
      for x in 0..p_arr.COUNT - 2 -- 2 less than previously, on each end of range
      loop  
。。。使用从索引-1开始的原始表填充得到相同的结果


循环中使用的索引必须与用于填充表的索引对齐,无论您如何操作。

对于x in 2..p_arr.COUNT循环如果p_arr(x)
。。。数组中有6项,但p_arr(4)是最后一项。难怪这会失败,因为p_arr(5)和p_arr(6)不存在……出于兴趣,为什么决定用从-1开始的索引填充表?我可以看出你可能会根据其他语言的行为选择零;但是为什么是-1呢?它是在任务I中指定的。我也在p_arr上尝试了FIRST、LAST、Previor和NEXT方法,但我无法使用它们实现排序。由于Alex Poole,案例已结束。保留原始代码作为参考还是编辑它更好?我尝试更改索引值和空值,暂时仍然是相同的错误。我正在Oralce Live SQL中运行此代码。在PLSQL Developer中也尝试了这个方法-同样的错误。@Alexound-我添加了一种调整循环索引的方法,包括一个指向实时SQL演示的链接。空球没有打破它,他们只是没有移动。亚历克斯,非常感谢你的帮助。看起来我错过了第二圈的“-2”。关于空值,您可以使用nvl()函数包装比较的两面,用相应的最小值或最大值替换空值。你只需要决定你想要空值的哪一端。是的,我会显式地检查空值,但是你必须在决定如何处理之前决定如何处理它们。