3

我创建了以下功能

function lob_replace( p_lob in out clob,p_what in varchar2,p_with in clob ) return clob
  as
      l_temp_number   number;
      l_temp_number_1 number;
      l_temp_clob clob;
      l_return_clob clob;
      l_temp1_clob clob;
      l_temp2_clob clob;
  begin
                l_temp_number:=dbms_lob.instr(p_lob, p_what);
                --Create a lob locator
                 DBMS_LOB.createtemporary(l_temp_clob,true);
                 DBMS_LOB.createtemporary(l_temp1_clob,true);
                 DBMS_LOB.createtemporary(l_temp2_clob,true);

                ---substract and build the LOBs
                l_temp_number_1:=length(p_lob);
                l_temp_clob:=dbms_lob.substr(p_lob,l_temp_number-1,1);
                l_temp1_clob:=dbms_lob.substr(p_lob,l_temp_number_1-l_temp_number+1 ,l_temp_number +length(p_what) );

                --append three diff lob to one
                dbms_lob.append(l_temp2_clob,l_temp_clob);
                dbms_lob.append(l_temp2_clob,p_with);
                dbms_lob.append(l_temp2_clob,l_temp1_clob);

                l_return_clob :=l_temp2_clob;

                --remove the tmp lob
                DBMS_LOB.freetemporary(l_temp_clob);
                DBMS_LOB.freetemporary(l_temp1_clob);
                DBMS_LOB.freetemporary(l_temp2_clob);

                return l_return_clob;
  end;

如果我如下调用此函数,这将引发错误

declare
   temp clob;
begin
  temp:='replace this #a#';
  temp:=lob_replace(temp,'#a#','with this');
end;

它会抛出以下错误

 ORA-06502: PL/SQL: numeric or value error: invalid LOB locator specified: ORA-22275
    ORA-06512: at "SYS.DBMS_LOB", line 639
    ORA-06512: at "LOB_REPLACE", line 24
    ORA-06512: at line 5

但这不会抛出错误

declare
   temp clob;
begin
  temp:='replace this #a# ';
  temp:=lob_replace(temp,'#a#','with this');
end;

请注意最后的额外空间temp:='replace this #a# ';

有谁知道这是什么原因?

4

1 回答 1

0

当你在建造l_temp1_clob时,你只能添加吊球的其余部分,如果有什么要添加的话。更改您的代码:

l_temp1_clob:=dbms_lob.substr(p_lob,l_temp_number_1-l_temp_number+1 ,l_temp_number +length(p_what) );

对此:

if l_temp_number +length(p_what) < l_temp_number_1
then
   l_temp1_clob := dbms_lob.substr(p_lob, l_temp_number_1 - l_temp_number - 1 , l_temp_number +length(p_what) );
end if;

逻辑是:如果 lob substr 的开始在 lob 的结束之前。

此外,该dd变量未在您的测试调用中声明:

declare
   temp clob;
begin
  temp:='replace this #a#';
  temp:=lob_replace(dd,'#a#','with this');
end;
于 2013-12-10T08:25:09.420 回答