我正在使用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;
答案 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;