如何使用UTL_FILE将大型CSV文件(文件大于32767)中的数据导入数据库

时间:2019-05-17 17:36:46

标签: plsql clob utl-file

我有一个具有90000条记录的csv文件,当我尝试在数据库中导入csv时,我遇到了以下错误-

错误报告- ORA-06502:PL / SQL:数字或值错误:字符串缓冲区太小 ORA-06512:位于“ AUTOLOCK.TEST_C1”的第136行 ORA-06512:在第1行 06502。00000-“ PL / SQL:数值或值错误%s” *原因:算术,数字,字符串,转换或约束错误            发生。例如,如果尝试执行以下操作,则会发生此错误            将值NULL分配给声明为NOT NULL的变量,或者            尝试将大于99的整数分配给变量            声明为NUMBER(2)。 *操作:更改数据,如何操作或声明数据            值不违反约束条件。

我知道缓冲区的大小是32767,而我的文件则更大。但是请告诉我如何使用UTL_FILE包处理这种情况。

下面是代码-

create or replace PROCEDURE test_c1(errbuff varchar2,errcode number)
AS
v_line                      VARCHAR2(32767);
v_file                      SYS.UTL_FILE.FILE_TYPE;
--v_dir                     VARCHAR2(250);
v_filename                  VARCHAR2(250);
p_ignore_headerlines  NUMBER;

BEGIN
v_filename := 'file.csv';       
v_file := SYS.UTL_FILE.FOPEN('CSV_DIR',v_filename,'R',32767);

p_ignore_headerlines:=1;
   IF p_ignore_headerlines > 0
   THEN
      BEGIN
         FOR i IN 1 .. p_ignore_headerlines
         LOOP
            UTL_FILE.get_line (v_file, V_LINE);
         END LOOP;
            END;
   END IF;

LOOP
BEGIN
SYS.UTL_FILE.GET_LINE(v_file,v_line);
EXCEPTION
WHEN no_data_found THEN
exit;
END;
INSERT INTO load_csv
VALUES (--my columns--);

END LOOP;
UTL_FILE.FCLOSE(v_file);
END;


/

我需要使用UTL_File Package加载数据。

1 个答案:

答案 0 :(得分:1)

错误“ ORA-06502”与文件大小无关,而与行大小有关。

变量“ v_line”用于32767字节,但该行具有更多字节。

您的Oracle数据库在哪个操作系统上?

如果是Windows,则行尾(或记录结束)必须为2(两个)字符:CARRIAGE_RETURN(ASCII 13十进制或十六进制值0D)和下一个LINE_FEED(ASCII 10十进制或十六进制值) 0A)。

如果是Linux / Unix,则行尾只能是1(一个)字符:LINE_FEED(ASCII 10)。

我建议使用十六进制编辑器(如XVI32),这样您就可以“看到”行尾。

在图像上为Windows系统的文本文件,带有CARRIAGE_RETURN(CR,ascii 13或十六进制值0D)和下一个LINE_FEED(LF,ascii 10或十六进制值0A)。

enter image description here

注意:如果要多次读取CVS文件(例如,每周或每月),则可以定义类型为“ 外部表”的表。让我知道可以帮助您。这样,您可以在CVS文件上使用“ 选择”,它比UTL_FILE快。