我想继续循环,即使没有数据找到并使用索引,通过'忘记找不到数据错误

时间:2015-07-16 23:11:11

标签: sql oracle plsql

我正在使用sqldeveloper。我必须为这个程序使用INDEX BY。

部门表格有ID's 10,20,50,60,80,100

目前程序打印id为10和20的dept_names,然后退出。

DECLARE
TYPE dept_table_indexby is TABLE OF
  departments.department_name%TYPE
  INDEX BY PLS_INTEGER;
dept_table_arr dept_table_indexby;
v_department_id  departments.department_id%TYPE := 10;
BEGIN 
  for i in 1..10 loop
  BEGIN
    select department_name into dept_table_arr(i)
    from departments
    where department_id = v_department_id;
    v_department_id := v_department_id + 10;
  EXCEPTION
    WHEN no_data_found THEN
    --null; /* tried this option, still control exits the loop */
    dbms_output.put_line('in loop : ' || dept_table_arr(i));
  end;
  end loop;

  for i in dept_table_arr.first..dept_table_arr.last loop
  dbms_output.put_line('department name: outside loop ' || dept_table_arr(i));
  end loop;

end;

3 个答案:

答案 0 :(得分:0)

我不确定错误在哪里。

我的猜测是因为当ID = 30时,你试图将NULL设置为dept_table_arr(i)

我不熟悉oracle sintaxis,但这是我的建议:

1 - 更容易,但我自己无法测试。

SELECT COALESCE(department_name , '') into dept_table_arr(i)
FROM departments
WHERE department_id = v_department_id;
  

COALESCE函数接受两个或多个兼容的参数,并返回非空的第一个参数。

2 - 更长但知道会起作用

SELECT COUNT(department_name) into int_department
FROM departments
WHERE department_id = v_department_id;

IF int_department > 0 THEN
    SELECT department_name into dept_table_arr(i)
    FROM departments
    WHERE department_id = v_department_id;
ELSE 
   dept_table_arr(i) := "";
END IF;

v_department_id := v_department_id + 10;

答案 1 :(得分:0)

您的代码中存在两个问题。

1)

 select department_name into dept_table_arr(i)
    from departments
    where department_id = v_department_id;
    v_department_id := v_department_id + 10;

no_data_found 发生时,v_department不会更新值,经过两次迭代后,它将始终保持为30。

2)

 for i in dept_table_arr.first..dept_table_arr.last loop
  dbms_output.put_line('department name: outside loop ' || dept_table_arr(i));
  end loop;

在此循环中, i 变量从1变为10(10次),但您的数组只有六个值。

修正错误后:

DECLARE
TYPE dept_table_indexby is TABLE OF
  departments.department_name%TYPE
  INDEX BY PLS_INTEGER;
dept_table_arr dept_table_indexby;
v_department_id  departments.department_id%TYPE := 0; --start with 0
k number;
BEGIN 
  for i in 1..10 loop
  BEGIN
    v_department_id := v_department_id + 10; --update v_department_id before select
    select department_name into dept_table_arr(i)
    from departments
    where department_id = v_department_id ; 

  EXCEPTION
    WHEN no_data_found THEN
    null; /* tried this option, still control exits the loop */
  end;
  end loop;
  --Associative arrays must be processed with .first and .next
  k:= dept_table_arr.first;
  while (k is not null)
    loop
--      dbms_output.put_line(k);
      dbms_output.put_line('department name: outside loop ' || dept_table_arr(k) );
      k:= dept_table_arr.next(k);
    end loop;
end;

答案 2 :(得分:0)

使用goto语句。 http://www.tutorialspoint.com/plsql/plsql_goto_statement.htm

BEGIN 
  for i in 1..10 loop
  BEGIN
    <<loopstart>> /* Where to start looping again when reach exception*/
    v_department_id := v_department_id + 10; --update in beginning like ksa said
    select department_name into dept_table_arr(i)
    from departments
    where department_id = v_department_id;

  EXCEPTION
    WHEN no_data_found THEN
    goto loopstart; /* Use this instead */
    dbms_output.put_line('in loop : ' || dept_table_arr(i));
  end;