当然会出错,在for i in 1..n loop语句中,i是一个自变量,怎能是一个固定数。每循环一步i就以步长增加。修改以下: i number:=0; begin ..... for v_sor in cur_begin loop .... i=i+1; if i>v_begin_rowcount then exit; end if end loop; ...
可以直接用 for i in 1..v_end_rowcount loop
end loop; 不必 i:=i+1;
既然i是一个变量,那么用游标的%rowcount属性替代它应该也是可以得呀,如: for cur_begin%rowcount in 1..v_end_rowcount loop ... ... end loop; 那为什么还有错误:PLS-00103出现符号"%"在需要下列之一时: in 不明白呀!!!
我的loop循环里包括fetch语句,也就是说,%rowcount的值是随着循环递增的,但还是有错误,我的语句为: <<outerloop>> --外层循环 FOR cur_begin%rowcount IN 0..v_begin_rowcount loop --循环条件:指针在表中记录范围内 <<innerloop>> --内层循环 FOR FETCH cur_end%rowcount IN 0..v_end_rowcount loop --循环条件:指针在表中记录范围内
FETCH cur_begin INTO v_begin_compare; --将起始站点放入变量中 FETCH cur_end INTO v_end_compare; --将终点站点放入变量中 if... ...
i number:=0;
begin
.....
for v_sor in cur_begin loop
....
i=i+1;
if i>v_begin_rowcount then
exit;
end if
end loop;
...
for i in 1..v_end_rowcount loop
end loop;
不必 i:=i+1;
for cur_begin%rowcount in 1..v_end_rowcount loop
... ...
end loop;
那为什么还有错误:PLS-00103出现符号"%"在需要下列之一时: in
不明白呀!!!
<<outerloop>> --外层循环
FOR cur_begin%rowcount IN 0..v_begin_rowcount loop --循环条件:指针在表中记录范围内
<<innerloop>> --内层循环
FOR FETCH cur_end%rowcount IN 0..v_end_rowcount loop --循环条件:指针在表中记录范围内
FETCH cur_begin INTO v_begin_compare; --将起始站点放入变量中
FETCH cur_end INTO v_end_compare; --将终点站点放入变量中
if... ...
FETCH cur_begin INTO v_begin_compare;
FETCH cur_end INTO v_end_compare;
EXIT WHEN cur_begin%NOTFOUND;
......
end loop;
修改之后的函数如下:
CREATE OR REPLACE FUNCTION fun_checksame(
i_begin_address tb_addressname.bus_stop%type,
i_end_address tb_addressname.bus_stop%type) --编写不用换车,一次到达的函数
RETURN pack_main.rec_check_output_type --返回一个记录类型
IS
checkdone boolean :=false; --false 不能到达;true 可以到达;
addressnum number(2); --用于存放经过的站数;
minaddress number(5) :=99999; --用于存放经过的最小站数;
v_begin_rowcount number(10) :=0; --用于存放供选择的源站点的车次数
v_end_rowcount number(10) :=0; --用于存放供选择的目的站点的车次数
v_begin_compare tb_begin_tem.bus_name%type;--用于存放游标选择的源站点的车次,供比较用
v_end_compare tb_end_tem.bus_name%type;--用于存放游标选择的目的站点的车次,供比较用
v_begin_id tb_begin_tem.bus_id%type;
v_end_id tb_end_tem.bus_id%type; --用于比较站点之间的顺序
i_begin_count number(10) :=1; --存放游标取回的记录数
i_end_count number(10) :=1; --存放游标取回的记录数
rec_check_output pack_main.rec_check_output_type; --声明一个用于输出查询结果的记录 CURSOR cur_begin --声明指向起始站临时表的游标
IS
SELECT bus_name from tb_begin_tem;
CURSOR cur_end --声明指向终点站临时表的游标
IS
SELECT bus_name from tb_end_tem;BEGIN
SELECT COUNT(bus_id) INTO v_begin_rowcount from tb_begin_tem;--得到起始站临时表的记录数
SELECT COUNT(bus_id) INTO v_end_rowcount from tb_end_tem; --得到终点站临时表的记录数
OPEN cur_begin;
OPEN cur_end;
<<outerloop>> --外层循环
FOR i_begin_count IN 1..v_begin_rowcount loop --循环条件:指针在表中记录范围内
FETCH cur_begin INTO v_begin_compare; --将起始站点放入变量中
<<innerloop>> --内层循环
FOR i_end_count IN 1..v_end_rowcount loop --循环条件:指针在表中记录范围内
FETCH cur_end INTO v_end_compare; --将终点站点放入变量中
IF v_begin_compare = v_end_compare THEN --条件:起始站点车次等于终点站点车次
SELECT bus_id
INTO v_begin_id
FROM tb_begin_tem
WHERE bus_name = v_begin_compare; --将乘坐的车次放入比较变量中
SELECT bus_id
INTO v_end_id
FROM tb_end_tem
WHERE bus_name = v_end_compare; --将乘坐的车次放入比较变量中
IF v_begin_id < v_end_id THEN --比较起始站点和终点站点的编号大小
addressnum := v_end_id - v_begin_id;
ELSE
addressnum := v_begin_id - v_end_id; --将经过站数放入变量中
END IF;
/*得到经过站数最少的车次*/
IF addressnum < minaddress THEN --比较站数来得到最短路线
pack_main.rec_check_output.bus_stop_count := addressnum; --经过站数送记录
minaddress := addressnum; --更新最小站数
pack_main.rec_check_output.bus_begin_name := v_begin_compare; --乘坐的车次送记录
pack_main.rec_check_output.bus_begin_stop := i_begin_address; --起始站送记录
pack_main.rec_check_output.bus_end_stop := i_end_address; --终点站送记录
END IF;
checkdone := true; --满足上述过程则证明可以到达
END IF;
EXIT outerloop WHEN cur_begin%NOTFOUND; --已经遍历完起始站点临时表
END LOOP innerloop;
END LOOP outerloop;CLOSE cur_begin;
CLOSE cur_end;IF checkdone THEN
pack_main.rec_check_output.check_count := 1; --查询次数送记录
DBMS_OUTPUT.PUT_LINE('换车次数为:'||''||
pack_main.rec_check_output.check_count-1||
''||'经过站数为:'||
pack_main.rec_check_output.bus_stop_count||
''||'请乘坐:'||''||
pack_main.rec_check_output.bus_begin_name||''||
pack_main.rec_check_output.bus_begin_stop||'----->'||
pack_main.rec_check_output.bus_end_stop); --输出查询结果
END IF;EXCEPTION
WHEN others THEN
DBMS_OUTPUT.PUT_LINE('EXIST ERRORS');
ROLLBACK;END fun_checksame;
我定义了一个记录类型,放在pack_main的包中,然后又在本函数中定义了一个记录rec_pack_output,我想利用这个记录来输出结果的查询信息,结果出现了以下的错误:
LINE/COL ERROR
-------- --------------------------------------------
57/12 PL/SQL: Statement ignored
57/22 PLS-00302: 必须说明 'REC_CHECK_OUTPUT' 组件
59/12 PL/SQL: Statement ignored
59/22 PLS-00302: 必须说明 'REC_CHECK_OUTPUT' 组件
60/12 PL/SQL: Statement ignored
60/22 PLS-00302: 必须说明 'REC_CHECK_OUTPUT' 组件
61/12 PL/SQL: Statement ignored
61/22 PLS-00302: 必须说明 'REC_CHECK_OUTPUT' 组件
74/6 PL/SQL: Statement ignored
74/16 PLS-00302: 必须说明 'REC_CHECK_OUTPUT' 组件
75/6 PL/SQL: Statement ignoredLINE/COL ERROR
-------- --------------------------------------------
76/37 PLS-00302: 必须说明 'REC_CHECK_OUTPUT' 组件请高手帮忙!
rec_check_output pack_main.rec_check_output_type; --声明一个用于输出查询结果的记录但在程序中又见到类以下这些语句:
pack_main.rec_check_output.bus_stop_count := addressnum; --经过站数送记录当然发生错误,既然声明了,就不必为它赋予包名了,而表记录属于对象类型,基本上要定义才能使用.省去包头名吧.
rec_check_output.bus_stop_count := addressnum; --经过站数送记录