ORA-22905:无法从非嵌套项访问行 之解决

今天笔者在帮同事写一个格式化日期函数的过程中,在调用管道(pipeline) 实现的函数时,遇到了一个ORACLE异常: ORA-22905:无法从非嵌套项访问行.

注:(有关嵌套表参见:http://blog.csdn.net/simonezhlx/archive/2008/10/28/3167343.aspx)

具体情况:为了实现日期字符串的格式化,需要对传入的字符串进行分拆.然后视情况补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;

红色为修改后内容,但是始终不知道为什么使用参数方式会有问题.如有知者告之,笔者甚感之至.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值