oracle ORA-06502:PL/SQL:数字或值错误:批量绑定:截断绑定
Posted
技术标签:
【中文标题】oracle ORA-06502:PL/SQL:数字或值错误:批量绑定:截断绑定【英文标题】:oracle ORA-06502: PL/SQL: numeric or value error: Bulk Bind: Truncated Bind 【发布时间】:2014-03-23 18:54:19 【问题描述】:当使用游标批量收集 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 多个表的结果,但只有 1 个表崩溃。 提前感谢您的帮助
【问题讨论】:
可能是因为clob
列,如上一个问题所述。有兴趣看到这一点得到证实。
@Alex.. 如果我将 clob 转换为 char 并将结果写入文件.. 那么 sqlloader 将如何尝试输入数据,因为您正确提到它可能需要特殊处理?
我相信您需要将每个 clob
写入一个单独的文件,以便 SQL*Loader 然后可以引用该文件;如之前的artice I linked to 所示。不过我没试过。
@alex.. 我看了你上面提供的文章.. 我想问你“数据文件中的文件名列被标记为 FILLER,所以它们没有加载到表中,但它们是在 LOBFILE 定义中用于标识 LOB 信息的位置。”我真的需要这些专栏吗?我将在数据文件和加载程序的控制文件中写入所有内容,我将添加 clob_content LOBFILE TERMINATED BY EOF,因为在调用加载程序时,我通过命令中的参数提供控制和数据。上述列定义的说法正确吗?
每个 LOB 值都必须在其自己的文件中。如果您的表有 100 行,那么您将有 100 个 LOB 文件,以及您已经创建的文件中的其余数据,该文件中的每一行都指向特定于行的 LOB 文件名。所以你必须在数据文件中有那个 LOB 文件名;但相关的 LOB 已加载到位。
【参考方案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_2
和 column2_3
具有相应的 CLOB 值。
然后,如果我使用该数据文件和可用的 CLOB 文件以及控制文件运行 SQL*Loader:
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
(我仍然认为您应该使用内置工具、数据泵或只是在两个模式之间在内部复制数据,如先前问题中所述...)
【讨论】:
非常感谢亚历克斯的帮助和支持。这对我现在唯一关心的问题非常有帮助,毕竟这就是你最后所说的。也许使用带有 clob 列的表的数据泵实用程序并只导出和导入数据会更有效。但我可以告诉你,虽然使用 sqlloader 让我有机会丰富我对光标函数和写入文件的知识,包括 linux 的 shell 脚本 在这一点上,也许我会画线并使用数据泵,因为当您必须导出具有 clob 列的数千行时会发生什么......最终会写出数千文件,然后导入数千个文件。因此,正如您建议的那样,数据泵在这张桌子上会更有效【参考方案2】:我收到了这个 EXACT 错误,但这是由于我将 Ref 游标返回的结果存储到集合中的一个字段中,该字段太小而无法存储该值。该字段被定义为 VARCHAR2(25 CHAR) 但是我试图在该字段中存储超过 25 个字符。
花了一点时间来剖析。关键是缩小错误发生的确切位置,并且当 Ref Cursor 将数据提取到我的集合中时它是正确的。
FETCH rc BULK COLLECT INTO [collection]
希望这对某人有所帮助。
【讨论】:
以上是关于oracle ORA-06502:PL/SQL:数字或值错误:批量绑定:截断绑定的主要内容,如果未能解决你的问题,请参考以下文章
Oracle ORA-06502 PL/SQL:数字或值错误:字符到数字的转换错误
Oracle 存储过程无法生成 csv 文件 - ORA-06502: PL/SQL: numeric or value error: string buff
Oracle.DataAccess.Client.OracleException ORA-06502:PL/SQL:数字或值错误:字符串缓冲区太小。 ExecuteReader 步骤出错