急,求助,100分,游标问题,快要烦死了!
同样一个功能,我用了隐式游标和显示游标来做,分别存在下面的问题搞不掂:
隐式游标:
create or replace procedure bdtreepro
as
cursor c_gdj is select id,miscode,miscontent from bdtree where type='1' and lev='1';
sqlstr varchar2(200);
tn varchar2(20);
begin
--定义一个表名字符串
tn:='ngsc.GZBD_BDZDAWH';
insert into bdtree(id,name,type,lev,pid,miscode,miscontent,tablename,remark)
select bdtreeseq.nextval,gdjmc,'1','1','000','GDJDM',gdjdm,'SYSCOM.GZXT_GDJDM',jc
from SYSCOM.GZXT_GDJDM where gdjdm<>'450000';
for row in c_gdj loop
sqlstr:='insert into bdtree(id,name,type,lev,pid,miscode,miscontent,tablename,remark)';
sqlstr:=sqlstr||'select bdtreeseq.nextval,bdzmc,''1'',''2'','||row.id||',''GZBD_BDZDAWH'',bdzbh,''GZBD_BDZDAWH'','||row.miscode;
--sqlstr:=sqlstr||' from '||row.remark||'sc.GZBD_BDZDAWH';
sqlstr:=sqlstr||' from '||tn;
execute immediate sqlstr;
end loop;
commit;
end;
上面的存储过程执行一切正常,但是因为我的游标cursor c_gdj is select id,miscode,miscontent from bdtree where type='1' and lev='1';定义时的where语句的条件where type=变量 and lev=变量
要是用隐式游标应该怎么做?后来我改成用带参数的显示游标来做。
显示游标:
create or replace procedure bdtreepro2
as
cursor c_bdz(v_type varchar2,v_lev varchar2) is select id,remark from bdtree
where type=v_type and lev=v_lev; --声明游标
sqlstr varchar2(200);
tn varchar2(20);
v_id varchar(10);
v_remark varchar2(10);
begin
--定义一个表名字符串
tn:='ngsc.GZBD_BDZDAWH';
--插入供电局信息
insert into bdtree(id,name,type,lev,pid,miscode,miscontent,tablename,remark)
select bdtreeseq.nextval,gdjmc,'1','1','000','GDJDM',gdjdm,'SYSCOM.GZXT_GDJDM',jc
from SYSCOM.GZXT_GDJDM where gdjdm<>'450000';
--插入变电站信息
if c_bdz%isopen=false then --如果游标没有打开
open c_bdz('1','1');
end if;
fetch c_bdz into v_id,v_remark;
while c_bdz%found
loop
sqlstr:='insert into bdtree(id,name,type,lev,pid,miscode,miscontent,tablename,remark)';
sqlstr:=sqlstr||'select bdtreeseq.nextval,bdzmc,''1'',''2'','||v_id||',''GZBD_BDZDAWH'',bdzbh,''GZBD_BDZDAWH'','||v_id;
--sqlstr:=sqlstr||' from '||row.remark||'sc.GZBD_BDZDAWH';
sqlstr:=sqlstr||' from '||tn;
execute immediate sqlstr;
end loop;
close c_bdz;
commit;
end;
结果一执行,就停不下来了,好像死循环似的,怎么回事啊?另外还有一个问题,无论是显示还是隐式游标,我都cursor c_gdj is select id,miscode,miscontent 定义了id,miscode,miscontent 三个字段,可是使用id,miscode都正常,用到miscontent就说无效列名,为什么啊?高手们帮帮忙,我要晕死了,:(
问题点数:100、回复次数:12Top
1 楼lqlling(水晶百合)回复于 2005-06-01 10:18:32 得分 0
不好意思,头昏了,我用的都是显示游标,只是两种不同的使用方式而已,要open游标那种使用不正常,一运行就停不下来,用for那个就正常,为何?另外,还是有那个无效列名的问题,为何呢?Top
2 楼lqlling(水晶百合)回复于 2005-06-01 10:35:21 得分 0
我又发现我的说的无效列名的问题了,因为miscontent字段是字符型的,我在sql语句里面没有给字段两边加上单引号。Top
3 楼nowait(独行天涯路)回复于 2005-06-01 10:58:27 得分 20
你loop的地方错了,肯定是死循环。
把 if c_bdz%isopen=false then --如果游标没有打开
open c_bdz('1','1');
end if;
fetch c_bdz into v_id,v_remark;
while c_bdz%found
loop
改为
if c_bdz%isopen=false then --如果游标没有打开
open c_bdz('1','1');
end if;
loop
fetch c_bdz into v_id,v_remark;
while c_bdz%found;
Top
4 楼lqlling(水晶百合)回复于 2005-06-01 11:19:10 得分 0
可是这样改后又报语法上的错误了.Top
5 楼liyan318(ly)回复于 2005-06-01 14:15:19 得分 10
(id,name,type,lev,pid,miscode,miscontent,tablename,remark)
remark是保留字,(id,name,type,lev,pid,miscode,miscontent,tablename,"remark")
把表结构给我,不然我调不起来。Top
6 楼liyan318(ly)回复于 2005-06-01 14:16:36 得分 0
bdtree和GZXT_GDJDM的这两张表的Top
7 楼LGQDUCKY(飘)回复于 2005-06-01 15:17:06 得分 0
刘 巧 玲:::应该是你吧~~~呵呵
你应该解决了吧, nowait(独行天涯路) 兄弟已经看出了原因
不过你还可以使用
if c_bdz%isopen=false then --如果游标没有打开
open c_bdz('1','1');
end if;
LOOP
BEGIN
fetch c_bdz into v_id,v_remark;
EXIT WHEN c_bdz%NOTFOUND;
sqlstr := 。。。。
BEGIN
execute immediate sqlstr;
EXCEPTION
WHEN OTHERS THEN
--INSERT 写一个出错表,没有写进的记录
END;
END;
END LOOP;
。。。。Top
8 楼LGQDUCKY(飘)回复于 2005-06-01 15:18:57 得分 0
我的QQ 80610318Top
9 楼zsfww1205(努力学习oracle)回复于 2005-06-01 17:13:05 得分 20
试试看这样行不行
open c_bdz;
fetch c_bdz into v_id,v_remark;
loop
exit when not c_bdz%found;
......
fetch c_bdz into v_id,v_remark;
end loop;
close c_bdz;
Top
10 楼lqlling(水晶百合)回复于 2005-06-01 18:00:36 得分 0
我的存储过程写完了,不过我是用for循环那种方式的,另外那个有时间再试试大家说的,呵呵,时间紧张。再问,我要在存储过程中
--删除序列
drop sequence bdtreeseq;
--创建序列
CREATE SEQUENCE bdtreeseq
INCREMENT BY 1
START WITH 1
NOMAXVALUE
NOCYCLE;
应该把这些语句放在哪里呢?Top
11 楼LGQDUCKY(飘)回复于 2005-06-01 18:12:04 得分 50
这些也要动态执行
sqlstr:=‘drop sequence bdtreeseq’;
execute immediate sqlstr;
sqlstr:='CREATE SEQUENCE bdtreeseq
INCREMENT BY 1
START WITH 1
NOMAXVALUE
NOCYCLE';
execute immediate sqlstr;
Top
12 楼lqlling(水晶百合)回复于 2005-06-02 16:09:36 得分 0
原来如此,好,多谢各位了,结贴.Top




