辅导:ORA-22905:无法从非嵌套项访问行的解决方法
来源:优易学  2011-10-31 13:15:47   【优易学:中国教育考试门户网】   资料下载   IT书店
  一个格式化日期函数的过程中,在调用管道(pipeline) 实现的函数时,遇到了一个ORACLE异常: ORA-22905:无法从非嵌套项访问行.
  具体情况:为了实现日期字符串的格式化,需要对传入的字符串进行分拆.然后视情况补0后再连接成一个字符串.
  为了实现该应用,创建了一个类型,两个函数.如下:
  --创建类型
  create or replace type type_split as table of varchar2(50);
  --创建通用Split函数
  create or replace function CommonSplit(sourceStr in varchar2,sepmark in varchar2)
  return TYPE_SPLIT pipelined is
  l_idx integer;
  v_list varchar2(500) := sourceStr;
  begin
  loop
  l_idx := instr(v_list,sepmark);
  if l_idx > 0 then
  pipe row(substr(v_list,1,l_idx-1));
  v_list := substr(v_list,l_idx+length(sepmark));
  else
  pipe row(v_list);
  exit;
  end if;
  end loop;
  return;
  end CommonSplit;
  --创建日期格式化函数
  create or replace function FormatDateStr(SourceDate in varchar2)
  return varchar2 is
  sReturnValue varchar2(8);
  SepMark varchar2(1):='-';
  sTemp varchar2(20);
  cursor cu1(p1 varchar2,p2 varchar2)
  is select * from table(COMMONSPLIT(p1,p2)) ;
  begin
  if LENGTH(SourceDate) <= 8 then
  --八位或不满足条件的输入日期
  sReturnValue := SourceDate;
  else
  if instr( SourceDate,SepMark ) > 0 then
  open cu1(SourceDate,SepMark);
  loop
  fetch cu1 into sTemp;
  exit when cu1%notfound;
  if length(sTemp) = 1 then --补0
  sTemp:= '0' || sTemp;
  end if;
  sReturnValue:= sReturnValue || sTemp;
  end loop;
  close cu1;
  end if;
  end if;
  return(sReturnValue);
  end FormatDateStr;
  但编写完成在测试时发现在运行到红色字体也就是运行游标查询时会有异常出现(ORA-22905:无法从非嵌套项访问行).
  尝试多次,均无果,最后只得变换方式,将游标改为无参,靠生成动态SQL来完成游标查询.结果问题解决.如下:
  create or replace function FormatDateStr(SourceDate in varchar2)
  return varchar2 is
  sReturnValue varchar2(8);
  SepMark varchar2(1):='-';
  sTemp varchar2(20);
  V_SQL_SELECT VARCHAR2(400);
  TYPE V_CURSOR IS REF CURSOR;
  cu1 V_CURSOR;
  -- cursor cu1(p1 varchar2,p2 varchar2)
  -- is select * from table(COMMONSPLIT(p1,p2)) ;
  -- is select * from table(commonsplit('' || p1 || '','' || p2 || ''));
  begin
  if LENGTH(SourceDate) <= 8 then
  --八位或不满足条件的输入日期
  sReturnValue := SourceDate;
  else
  if instr( SourceDate,SepMark ) > 0 then
  --open cu1(SourceDate,SepMark);
  V_SQL_SELECT:='select * from table(COMMONSPLIT(''' || SourceDate
  || ''',''' || SepMark || '''))';
  open cu1 for V_SQL_SELECT;
  loop
  fetch cu1 into sTemp;
  exit when cu1%notfound;
  if length(sTemp) = 1 then --补0
  sTemp:= '0' || sTemp;
  end if;
  sReturnValue:= sReturnValue || sTemp;
  end loop;
  close cu1;
  end if;
  end if;
  return(sReturnValue);
  end FormatDateStr;

责任编辑:小草

文章搜索:
 相关文章
热点资讯
热门课程培训