oracle ORA-06502:PL / SQL:数字或值错误:Bulk Bind:Truncated Bind

时间:2014-03-23 18:54:19

标签: oracle plsql cursor

当使用游标在sys.odcivarchar2list中批量收集结果时,我收到此错误: ORA-06502:PL / SQL:数值或值错误:批量绑定:截断绑定 我的循环执行多次没有错误,但仅针对特定的表我将所有数据收集到varchar2列表中我收到此错误。我用了这段代码:

declare
  filehandle1 utl_file.file_type;
  myquery varchar2(4000) := 'select column1 ||''~''|| column2 from mytable';
  mycursor sys_refcursor;
  myresults sys.odcivarchar2list;
begin
  filehandle1 := utl_file.fopen ('D42', 'mydata', 'w');
  open mycursor for myquery; 
  loop
   fetch mycursor bulk collect into myresults;
if myresults.count>0 Then
    for idx in myresults.first..myresults.last loop
      utl_file.put_line(filehandle1, myresults(idx));
    end loop;
End if;
    exit when mycursor%notfound;
  end loop;
  close mycursor;
  utl_file.fclose(filehandle1);
end;

这将返回超过100个表的结果,但只有一个表崩溃。 提前感谢您的帮助

2 个答案:

答案 0 :(得分:1)

您需要将每个CLOB值写入单独的文件中,并将该文件名作为主数据记录的一部分包含在内。像这样:

declare
  data_file utl_file.file_type;
  clob_file utl_file.file_type;
  buffer varchar2(32767);
  position pls_integer;
  chars pls_integer;

  myquery varchar2(4000) := 'select column1 ||''~''|| column3, '
    || '''column2_'' || rownum, column2 from mytable';
  mycursor sys_refcursor;
  myresult varchar2(4000);
  myfilename varchar2(120);
  myclob clob;
begin
  data_file := utl_file.fopen ('D42', 'mydata', 'w');
  open mycursor for myquery; 
  loop
    fetch mycursor into myresult, myfilename, myclob;
    exit when mycursor%notfound;
    if myclob is not null and dbms_lob.getlength(myclob) > 0 then
      myresult := myresult ||'~'|| myfilename;
      clob_file := utl_file.fopen ('D42', myfilename, 'w', 32767);
      position := 1;
      chars := 32767;
      while position < dbms_lob.getlength(myclob) loop
        dbms_lob.read(myclob, chars, position, buffer);
        utl_file.put(clob_file, buffer);
        utl_file.fflush(clob_file);
        position := position + chars;
      end loop;
      utl_file.fclose(clob_file);
    end if;
    utl_file.put_line(data_file, myresult);
  end loop;
  close mycursor;
  utl_file.fclose(data_file);
end;
/

有一个data_file包含所有非CLOB数据,包括您写入该行CLOB的单个文件的名称。文件名可以是任何东西,只要它是唯一的;我使用了rownum但您可以使用行的主键ID(例如,如果有)。

将虚拟表创建为:

create table mytable (column1 number, column2 clob, column3 varchar2(10));
insert into mytable (column1, column2, column3) values (1, null, 'First');
insert into mytable (column1, column2, column3) values (2, 'Second CLOB', 'Second');
insert into mytable (column1, column2, column3) values (3, 'Third CLOB', 'Third');

..这会创建包含以下内容的mydata

1~First
2~Second~column2_2
3~Third~column2_3

和文件column2_2column2_3以及相应的CLOB值。

然后,如果我运行带有该数据文件的SQL * Loader和可用的CLOB文件,以及控制文件:

load data
characterset UTF8
truncate
into table mytable2
fields terminated by "~"
trailing nullcols
(
  column1 char(10),
  column3 char(10),
  clob_filename filler char(120),
  column2 lobfile(clob_filename) terminated by EOF
)

...新表格填充为:

select * from mytable2;

   COLUMN1 COLUMN2                        COLUMN3  
---------- ------------------------------ ----------
         1                                First      
         2 Second CLOB                    Second
         3 Third CLOB                     Third

(我仍然认为你应该使用内置工具,数据泵或只是在两个模式之间内部复制数据,如前面的问题所讨论的那样......)

答案 1 :(得分:0)

我收到此“确切”错误,但是这是由于我将结果保存到引用光标返回到集合中的一个字段中而导致该结果太小而无法存储该值。该字段定义为VARCHAR2(25 CHAR),但是我试图在此字段中存储25个以上的字符。

花点时间进行剖析。关键是准确地缩小发生错误的位置,这是正确的,因为Ref Cursor正在将数据捕获到我的集合中。

FETCH rc BULK COLLECT INTO [collection]

希望这对某人有帮助。